web-dev-qa-db-ja.com

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<Product> products = await response.Content.ReadAsAsync<ObservableCollection<Product>>();
    }

しかし、シリアライザーはodata.metadata部分とそこに2つのodata.typeレコードがあるという事実を好まないようです(それらが何であるかはわかりません)。

これを行う簡単な方法はありますか?

21
Graeme

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; }
}
35
L.B

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

Visual Studioを使用している場合、素晴らしいCLRクラス生成機能が組み込まれています。

  1. ODataペイロードをクリップボードにコピーします
  2. Visual Studioで、メニューオプション編集-> 特殊貼り付け-> JSONをオブジェクトクラスとして貼り付けを選択します。

その後、Json.NETを使用して、これらのクラスにデシリアライズします(L.Bの回答を参照)。

8
ScottB

ODataサービスを直接使用するための.NETクライアントがあります。 V3 odataサービスの場合、 Simple.OData.ClientOData v1-3のODataLib で試すことができます。 V3 ODataサービスの場合、 OData Client Code Generator で試すことができます。 ODataクライアントのその他のライブラリについては、 http://www.odata.org/libraries/ を参照できます。

3
QianLi

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を使用することは、コードが非同期ではないため最良の方法ではないかもしれませんが、私のアプリケーションでは重要ではなく、コードの行数を少なくしました。

1
Rand0mChar