如何反序列化oData JSON?

时间:2014-11-08 18:00:06

标签: c# json odata

我正在尝试使用Northwind OData服务:

http://services.odata.org/V3/OData/OData.svc/Products?$format=json

并将其反序列化为一组产品:

    using (var client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(new Uri(url));
        ObservableCollection<Product> products = await response.Content.ReadAsAsync<ObservableCollection<Product>>();
    }

但序列化程序似乎不喜欢odata.metadata部分以及有2 odata.type个记录的事实(不确定它们是什么)。

有一种简单的方法吗?

5 个答案:

答案 0 :(得分:33)

使用Json.Net

using (var client = new HttpClient())
{
    var json = await client.GetStringAsync("http://services.odata.org/V3/OData/OData.svc/Products?$format=json");
    var odata = JsonConvert.DeserializeObject<OData>(json);
}

public class Value
{
    [JsonProperty("odata.type")]
    public string Type { set; get; }
    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime ReleaseDate { get; set; }
    public DateTime? DiscontinuedDate { get; set; }
    public int Rating { get; set; }
    public double Price { get; set; }
}

public class OData
{
    [JsonProperty("odata.metadata")]
    public string Metadata { get; set; }
    public List<Value> Value { get; set; }
}

答案 1 :(得分:13)

为odata的响应定义一个类(它是一个通用的定义,所以你可以在任何类型中使用它):

internal class ODataResponse<T>
 {
    public List<T> Value { get; set; }
 }

反序列化如下:

using (var client = new HttpClient())
 {
     HttpResponseMessage response = await client.GetAsync(new Uri(url));
     var json = await response.Content.ReadAsStringAsync();
     var result = JsonConvert.DeserializeObject<ODataResponse<Product>>(json);
     var products = result.Value;
 }

答案 2 :(得分:7)

如果您使用的是Visual Studio,则内置了一个非常棒的CLR Class Generation功能。

  1. 将OData有效负载复制到剪贴板
  2. 在Visual Studio中,选择菜单选项修改 - &gt; 选择性粘贴 - &gt;将JSON粘贴为对象类
  3. 然后,您可以使用Json.NET反序列化到这些类中(如L.B&#39的回答中所述)。

答案 3 :(得分:3)

有.NET客户端直接使用OData服务。对于V3 odata服务,您可以尝试使用Simple.OData.ClientODataLib for OData v1-3。对于V3 OData服务,您可以尝试使用OData Client Code Generator。 OData客户端的其他库,您可以参考http://www.odata.org/libraries/

答案 4 :(得分:0)

管理odata.metadata部分引起的反序列化问题的另一种可能方法是请求odata响应不包含元数据。这可以通过http客户端中的默认请求标头来完成:

client.DefaultRequestHeaders.Add("Accept", "application/json;odata.metadata=none");

这允许使用ReadAsAsync对对象进行反序列化:

var products = response.Content.ReadAsAsync<Dictionary<string, ObservableCollection<Product>>>().Result["value"]

这似乎比编写另一个类来处理响应更清晰。使用.Result可能不是最好的方法,因为代码不是异步的,但它在我的应用程序中并不重要,并使代码占用更少的行。