web api响应中的额外花括号使响应无法转换为模型

问题描述 投票:1回答:3

我正在尝试阅读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模型。

她是我得到的回应。

{{“business”:[{“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”:“seafood”,“title”:“Seafood”},{“alias” :“海鲜市场”,“标题”:“海鲜市场”},{“别名”:“raw_food”,“标题”:“生活/生食”},“评级”:4.5,“坐标”:{“纬度“:37.795831,”经度“:-122.393303},”交易“:[],”价格“:”$$“,”位置“:{”address1“:”1 Ferry Bldg“,”address2“:”“, “address3”:“Shop 11”,“city”:“旧金山”,“zip_code”:“94111”,“country”:“US”,“state”:“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“,”别名“:”kokkari-estiatorio-san-francisco“,”name“:”Kokkari Estiatorio“,”image_url“:”“,”is_closed“:false,”url“:”“ ,“review_count”:430 0,“类别”:[{“alias”:“greek”,“title”:“Greek”},{“alias”:“mediterranean”,“title”:“Mediterranean”}],“rating”:4.5, “coordinates”:{“latitude”:37.796996,“经度”:-122.399661},“transactions”:[“pickup”],“price”:“$$$”,“location”:{“address1”:“200 Jackson St“,”address2“:”“,”address3“:”“,”city“:”旧金山“,”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”,“别名”:“the-house-san-francisco”,“name”:“The House”,“image_url”:“”:false,“url”:“” ,“review_count”:4521,“类别”:[]}}

在响应的开始和结束处有一对额外的花括号。如何以适当的Json格式获取响应。

c# asp.net-mvc asp.net-web-api2 yelp yelp-fusion-api
3个回答
1
投票

呼唤

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


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;
}

-1
投票
 var business = all.Result;  
 var resultString = business.ReadAsStringAsync();  
 return JsonConvert.DeserializeObject<Common.Models.Yelp.Yelp>(resultString);
© www.soinside.com 2019 - 2024. All rights reserved.