Дополнительные фигурные скобки в ответе веб-API делают невозможным преобразование ответа в модель - PullRequest
1 голос
/ 07 марта 2019

Я пытаюсь прочитать 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=10&latitude={latitude}&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>().Result;
        var result = (Common.Models.Yelp.Yelp)(business);
        return result;
    }

Ответ, который я получаю от этого API, заключен в фигурные скобки, поэтому он не являетсячто позволяет мне преобразовать ответ в модель Yelp.

Это ответ, который я получаю.

{{"enterprises": [{"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": [{"alias": "морепродукты", "title": "Seafood"}, {"alias": "морепродукты", "title": "Marfood Markets"}, {"alias": "raw_food""," title ":" Live / Raw Food "}]," rating ": 4.5," arguments ": {" latitude ": 37.795831," longitude ": -122.393303}," Transactions ": []," Price ": "$$", "location": {"address1": "1 Ferry Bldg", "address2": "", "address3": "Shop 11", "city": "San Francisco", "zip_code":"94111", "страна": "США", "штат": "CA", "display_address": ["1 Ferry Bldg", "Магазин 11", "Сан-Франциско, CA 94111 "]}," phone ":" +14153917117 "," display_phone ":" (415) 391-7117 "," distance ": 1154.8167382059307}, {" id ":" PsY5DMHxa5iNX_nX0T-qPA "," alias ":"kokkari-estiatorio-san-francisco", "name": "Kokkari Estiatorio", "image_url": "", "is_closed": false, "url": "", "review_count": 4300, "Categories": [{"псевдоним": "греческий", "заголовок": "греческий"}, {"псевдоним": "средиземноморский", "заголовок": "средиземноморский"}], "рейтинг": 4.5, "координаты": {"широта": 37.796996," longitude ": -122.399661}," Transactions ": [" pickup "]," price ":" $$$ "," location ": {" address1 ":" 200 Jackson St "," address2 ": "", "address3": "", "city": "San Francisco", "zip_code": "94111", "country": "US", "state": "CA", "display_address": ["200 Jackson St "," San Francisco, CA 94111 "]}," phone ":" +14159810983 "," display_phone ":" (415) 981-0983 "," distance ": 1124.9562174585888}, {" id ":"ZoZjbOYR-apY8XvommlNUA "," alias ":" the-house-san-francisco "," name ":" The House "," image_url ":" ": false," url ":" "," review_count ": 4521,"кошкаegories ": []}}

В начале и конце ответа есть пара дополнительных фигурных скобок.Как я могу получить ответ в правильном формате Json.

Ответы [ 3 ]

0 голосов
/ 07 марта 2019
 var business = all.Result;  
 var resultString = business.ReadAsStringAsync();  
 return JsonConvert.DeserializeObject<Common.Models.Yelp.Yelp>(resultString);
0 голосов
/ 07 марта 2019

Используйте JSON.NET метод десериализации для десериализации из строки в желаемое 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=10&latitude={latitude}&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;
}
0 голосов
/ 07 марта 2019

Зов

all.ReadAsAsync<Object>().Result;

возвращает вам экземпляр 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.

...