#c# #asp.net-mvc #asp.net-web-api2 #yelp #yelp-fusion-api
#c# #asp.net-mvc #asp.net-web-api2 #yelp #yelp-fusion-api
Вопрос:
Я пытаюсь прочитать Yelp API. Ниже приведен мой код.
public async Task<HttpContent> InvokeApi(string path, HttpAction action, HttpContent content = null, TimeSpan? overrideTimeout = null, string externalServer = null)
{
var sUrl = externalServer == null ? ServerUrl : externalServer;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(sUrl);
if (overrideTimeout.HasValue)
{
client.Timeout = overrideTimeout.Value;
}
//this.Log("Connecting to {0} Api at {1}".Fmt(WebPortalServer, ServerUrl));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", AccessToken);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response;
switch (action)
{
case HttpAction.Get:
response = await client.GetAsync(path);
break;
case HttpAction.Post:
response = await client.PostAsync(path, content);
break;
case HttpAction.Put:
response = await client.PutAsync(path, content);
break;
case HttpAction.Delete:
response = await client.DeleteAsync(path);
break;
default:
throw new ArgumentOutOfRangeException("action", action, null);
}
return response.IsSuccessStatusCode ? response.Content : null;
}
}
Я вызываю вышеупомянутую функцию как
public async Task<Common.Models.Yelp.Yelp> GetAllBusiness(decimal latitude, decimal longitude)
{
var all = await _webPortalApiClient.InvokeApi($"businesses/search?limit=10amp;latitude={latitude}amp;longitude={longitude}", HttpAction.Get, null, null, "https://api.yelp.com/v3/");
if (all == null)
{
return null;
}
//var business = await all.ReadAsAsync<Common.Models.Yelp.Yelp>();
var business = all.ReadAsAsync<Object>().Resu<
var result = (Common.Models.Yelp.Yelp)(business);
return resu<
}
Ответ, который я получаю от этого api, заключен в фигурные скобки, из-за этого он не позволяет мне преобразовать ответ в модель Yelp.
Она — это тот ответ, который я получаю.
{{ «businesses»: [ { «id»: «Xg-FyjVKAN70LO4u4Z1ozg», «alias»: «hog-island-oyster-co-san-francisco», «name»: «Hog Island Oyster Co», «image_url»: «», «is_closed»: false, «url»: «», «review_count»: 5550, «categories»: [ { «псевдоним»: «морепродукты», «заголовок»: «Морепродукты»}, { «псевдоним»: «seafoodmarkets», «заголовок»: «Рынки морепродуктов»}, { «псевдоним»: «raw_food», «заголовок»: «Живые / сырые продукты» } ], «рейтинг»: 4.5, «координаты»: { «широта»: 37.795831, «долгота»: -122.393303 }, «транзакции»: [], «цена»: «$$», «местоположение»: { «адрес1» : «1 Паромный корп.», «адрес2»: «», «адрес3»: «Магазин 11», «город»: «Сан-Франциско», «почтовый индекс»: «94111», «страна»: «США», «штат»: «КАЛИФОРНИЯ», «display_address»: [ «1 паромный корп.», «Магазин 11», «Сан-Франциско, КАЛИФОРНИЯ 94111» ] }, «телефон»: » 14153917117″, «display_phone»: «(415) 391-7117″, » distance»: 1154.8167382059307 }, { «id»: «PsY5DMHxa5iNX_nX0T-qPA», «псевдоним»: «kokkari-estiatorio-san-francisco», «name»: «Kokkari Estiatorio», «image_url»: «», «is_closed»: false, «url»: «», «review_count»: 4300, «categories»: [ { «alias»: «греческий», «title»: «Греческий»}, { «alias»: «средиземноморский», «title»: «Средиземноморский» } ], «рейтинг»: 4.5, «координаты»: { «широта»: 37.796996, «долгота»: -122.399661}, «транзакции»: [ «самовывоз»], «цена»: «$$$», «местоположение»: { «адрес1»: «200 Jackson St», «адрес2»: «», «адрес3»: «», «город»: «Сан-Франциско», «почтовый индекс»: «94111», «страна»: «США», «штат»: » CA», «display_address»: [ «200 Jackson St», «Сан-Франциско, КАЛИФОРНИЯ 94111» ] }, «phone»: » 14159810983″, «display_phone»: «(415) 981-0983″, » distance»: 1124.9562174585888 }, { «id»: «ZoZjbOYR-apY8XvommlNUA», «псевдоним»: «the-house-san-francisco», «name»: «The House», «image_url»: «»: false, «url»: «», «review_count»: 4521, «categories»: []}}
В начале и в конце ответа есть пара дополнительных фигурных скобок. Как я могу получить ответ в надлежащем формате Json.
Комментарии:
1. Примечание: сделайте ваш HttpClient одноэлементным.
2. Опубликованный Json в любом случае недействителен. Double
{}
может быть случаем двойного кодирования или отсутствующей оболочки.3. используйте async:
var business = await all.ReadAsAsync<Object>();
Ответ №1:
Вызов
all.ReadAsAsync<Object>().Resu<
возвращает вам экземпляр, в JObject
который невозможно преобразовать Yelp
простым приведением. Вместо этого вызовите ReadAsAsync
вот так
var business = await all.ReadAsAsync<Common.Models.Yelp.Yelp>();
return business;
Если вы все еще хотите вызвать его с помощью object
, вы можете сделать это следующим образом
var business = await all.ReadAsAsync<object>();
return ((JObject)business).ToObject<Yelp>();
Примечание
Ответ json не содержит дополнительных фигурных скобок. Это просто JObject
добавляет их в отладочный вид. Это легко проверить, изучив результат чтения ответа в виде строки all.ReadAsStringAsync().Result
.
Комментарии:
1. на самом деле он должен быть правильно синхронизирован:
var business = await all.ReadAsAsync<Common.Models.Yelp.Yelp>();
2. Я попробовал вышеупомянутое решение, но получаю приведенную ниже ошибку { «Message»: «Произошла ошибка.», «ExceptionMessage»: «Входная строка ‘4.5’ не является допустимым целым числом. Путь ‘businesses[0].rating’, строка 1, позиция 634.», «ExceptionType»: «Newtonsoft.Json.JsonReaderException», «StackTrace»: «в Newtonsoft.Json. JsonTextReader. ParseReadNumber(ReadType readType, Char firstChar, Int32 initialPosition)r n в Newtonsoft.Json. JsonTextReader. ParseNumber(ReadType readType)r n в ……. }
Ответ №2:
Используйте JSON.NET Метод десериализации для десериализации из string в желаемый POCO с использованием перегрузки универсального типа.
public async Task<HttpContent> InvokeApi(string path, HttpAction action, HttpContent content = null, TimeSpan? overrideTimeout = null, string externalServer = null)
{
var sUrl = externalServer == null ? ServerUrl : externalServer;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(sUrl);
if (overrideTimeout.HasValue)
{
client.Timeout = overrideTimeout.Value;
}
//this.Log("Connecting to {0} Api at {1}".Fmt(WebPortalServer, ServerUrl));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", AccessToken);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response;
switch (action)
{
case HttpAction.Get:
response = await client.GetAsync(path);
break;
case HttpAction.Post:
response = await client.PostAsync(path, content);
break;
case HttpAction.Put:
response = await client.PutAsync(path, content);
break;
case HttpAction.Delete:
response = await client.DeleteAsync(path);
break;
default:
throw new ArgumentOutOfRangeException("action", action, null);
}
return response.IsSuccessStatusCode ? response.Content : null;
}
}
public async Task<Common.Models.Yelp.Yelp> GetAllBusiness(decimal latitude, decimal longitude)
{
HttpContent all = await _webPortalApiClient.InvokeApi($"businesses/search?limit=10amp;latitude={latitude}amp;longitude={longitude}", HttpAction.Get, null, null, "https://api.yelp.com/v3/");
if (all == null)
{
return null;
}
string responseBody = await all.ReadAsStringAsync();
// Deserialize from serialized string into your POCO
var business = JsonConvert.DeserializeObject<Common.Models.Yelp.Yelp>(responseBody);
return business;
}
Ответ №3:
var business = all.Resu<
var resultString = business.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Common.Models.Yelp.Yelp>(resultString);
Комментарии:
1. Привет и добро пожаловать в Stack Overflow. Рекомендуется добавить больше контекста (почему возникла проблема или почему это работает и что это за код, который устраняет проблему) к вашему ответу, чтобы его было легче понять OP и другим, кто приходит к нему.