如何反序列化oData JSON?
我正在尝试使用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 products = await response.Content.ReadAsAsync<ObservableCollection>(); }
但是序列化程序似乎不喜欢odata.metadata
部分以及那里有2个odata.type
记录的事实(不确定它们是什么)。
是否有捷径可寻?
使用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(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 { get; set; } }
为odata的响应定义一个类(它是一个通用的定义,所以你可以在任何类型使用它):
internal class ODataResponse { public List 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>(json); var products = result.Value; }
如果您使用的是Visual Studio,则内置了一个出色的CLR Class Generationfunction。
- 将OData有效负载复制到剪贴板
- 在Visual Studio中,选择菜单选项编辑 – > 选择性粘贴 – >将JSON粘贴为对象类
然后,您可以使用Json.NET反序列化到这些类中(如LB的答案中所述)。
有一个.NET客户端可以直接使用OData服务。 对于V3 odata服务,您可以尝试使用Simple.OData.Client , ODataLib for OData v1-3 。 对于V3 OData服务,您可以尝试使用OData客户端代码生成器 。 OData客户端的其他库,可以参考http://www.odata.org/libraries/ 。
管理odata.metadata
部分引起的反序列化问题的另一种可能方法是请求odata响应不包含元数据。 这可以使用http客户端中的默认请求标头来完成:
client.DefaultRequestHeaders.Add("Accept", "application/json;odata.metadata=none");
这允许使用ReadAsAsync对对象进行反序列化:
var products = response.Content.ReadAsAsync>>().Result["value"]
这似乎比编写另一个类来处理响应更清晰。 使用.Result
可能不是最好的方法,因为代码不是异步的,但它在我的应用程序中并不重要,并使代码占用更少的行。