Web API响应中多余的花括号使响应变得难以处理,无法转换为模型

时间:2019-03-07 15:19:58

标签: 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=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模型。

她是我得到的答复。

{{“企业”:[{“ id”:“ Xg-FyjVKAN70LO4u4Z1ozg”,“ alias”:“ hog-island-oyster-co-san-francisco”,“名称”:“ Hog Island Oyster Co”, “ image_url”:“”,“ is_closed”:否,“ url”:“”,“ review_count”:5550,“类别”:[{“ alias”:“ seafood”,“ title”:“ Seafood”},{ “ alias”:“ seafoodmarkets”,“ title”:“海鲜市场”},{“ alias”:“ raw_food”,“ title”:“生/生食物”}],“等级”:4.5,“坐标”: {“纬度”:37.795831,“经度”:-122.393303},“交易”:[],“价格”:“ $$”,“位置”:{“ address1”:“ 1 Ferry Bldg”,“ address2”: “”,“ address3”:“商店11”,“城市”:“旧金山”,“邮政编码”:“ 94111”,“国家”:“美国”,“州”:“ CA”,“ display_address”:[ “ 1 Ferry Bldg”,“ Shop 11”,“ San Francisco,CA 94111” ]},“ phone”:“ +14153917117”,“ display_phone”:“(415)391-7117”,“ distance”:1154.8167382059307},{“ id”:“ PsY5DMHxa5iNX_nX0T-qPA”,“ alias”:“ kokkari- estiatorio-san-francisco”,“名称”:“ Kokkari Estiatorio”,“ image_url”:“”,“ is_closed”:false,“ url”:“”,“ review_count”:4300,“类别”:[{ “:” greek“,” title“:”希腊“},{” alias“:” mediterranean“,” title“:” Mediterranean“}],”等级“:4.5,”坐标“:{”纬度“:37.796996 ,“经度”:-122.399661},“交易”:[“提取”],“价格”:“ $$$”,“位置”:{“ address1”:“ 200 Jackson St”,“ address2”:“” ,“ address3”:“”,“ city”:“旧金山”,“邮政编码”:“ 94111”,“国家”:“美国”,“州”:“ CA”,“ display_address”:[“ Jackson Jackson 200号“, “旧金山,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“:”“:假,” url“:”“,” review_count“:4521,”类别“:[]}}

响应的开始和结束处有一对多余的花括号。 如何获取正确的Json格式的响应。

3 个答案:

答案 0 :(得分:0)

的呼叫

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进行检查,很容易检查这一点。

答案 1 :(得分:0)

使用通用类型重载,使用JSON.NET的Deserialize method将字符串反序列化为所需的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;
}

答案 2 :(得分:-1)

 var business = all.Result;  
 var resultString = business.ReadAsStringAsync();  
 return JsonConvert.DeserializeObject<Common.Models.Yelp.Yelp>(resultString);