2012-05-02 3 views
1

System.Net.Http.HttpClient、the version currently available in NuGet、 を使用して、json形式のサービスからデータを取得しています。データは、おおよそ次のようになります。このデータスキーマでReadAsAsync <T>を使用するにはどうすればよいですか?

{ 
    "schema": "Listing", 
    "data": { 
    "key": "28ba648c-de24-45d4-a7d9-70f810cf5438", 
    "children": [{ 
     "kind": "type1", 
     "data": { 
     "body": "Four score and seven years ago...", 
     "parent_id": "2qh3l", 
     "report_count": 0, 
     "name": "c4j6yeh" 
     } 
    }, { 
     "kind": "type3", 
     "data": { 
     "domain": "abc.def.com", 
     "flagged": true, 
     "category": "news", 
     "saved": false, 
     "id": "t3dz0", 
     "created": 1335998011.0 
     } 
    }] 
    } 
} 

私はオブジェクトグラフにそのJSON文字列をデシリアライズするHttpContentExtensions.ReadAsAsync<T>を使用しています。型定義おおよそ次のようになります。

public class Response 
{ 
    public String schema { get;set; } 
    public ListingData data { get;set; } 
} 

public class ListingData 
{ 
    public string key { get;set; } 
    public List<OneItem> children { get;set; } 
} 

は、ここで問題です:私はkind性質に応じて変化することがchildrenにアイテムの種類を望みます。 kindが "type1"の場合、オブジェクトを逆シリアル化したいとします... Type1としましょう。 kindが "type3"の場合、タイプType3のオブジェクトが必要です。

今、List<Type1>またはList<Type3>を逆シリアル化できますが、デシリアライゼーションロジックに2つを区別する方法を知らせていません。

"type1"データオブジェクトと "type3"データオブジェクトのすべてのプロパティを1つの.NETタイプにマージできます。しかし、プロパティの数は、これが乱雑になるほど十分に大きいです。 (この場合はdataで)JSONのプロパティの名前が異なっていた場合は

、私はそれを使用して区別することができます。例えば、データがこのように見えた、場合:

"children": [{ 
     "kind": "type1", 
     "t1data": { ... } 
    }, { 
     "kind": "type3", 
     "t3data": { ... } 
    }] 

...その後、私は.NETでこのような何かを行うことができます:

public class OneItem 
{ 
    public string kind { get;set; } 
    public Type1 t1data { get;set; } 
    public Type3 t3data { get;set; } 
} 

しかし、私のデータスキーマは、そのようには見えません。

データの内容によって逆シリアル化のタイプを選択できますか?つまり、 は、あるプロパティ(この場合はkind)の値を調べて、別のプロパティ(この場合はdata)の内容を逆シリアル化する方法を決定します。

それともReadAsAsyncがそれをデシリアライズしようとする前に、JSONに作用するフィルタやトランスを注入することができますか?

もしそうなら、どのように?

答えて

0

あなたの応答にいくつかの前処理を行うのw/OKだとあなたがJson.NETを使用することができれば、あなたがやりたいことができるはずです。このテストに合格

public class Response 
{ 
    public string schema 
    { 
     get; 
     set; 
    } 

    public ListingData data 
    { 
     get; 
     set; 
    } 
} 

public class ListingData 
{ 
    public string key 
    { 
     get; 
     set; 
    } 

    public List<object> children 
    { 
     get; 
     set; 
    } 
} 

public class Type1 
{ 
    public string body 
    { 
     get; 
     set; 
    } 

    public string parent_id 
    { 
     get; 
     set; 
    } 

    public int report_count 
    { 
     get; 
     set; 
    } 

    public string name 
    { 
     get; 
     set; 
    } 
} 

public class Type3 
{ 
    public string domain 
    { 
     get; 
     set; 
    } 

    public bool flagged 
    { 
     get; 
     set; 
    } 

    public string category 
    { 
     get; 
     set; 
    } 

    public bool saved 
    { 
     get; 
     set; 
    } 

    public string id 
    { 
     get; 
     set; 
    } 

    public double created 
    { 
     get; 
     set; 
    } 
} 

[Test] 
public void RoundTrip() 
{ 
    var response = new Response 
         { 
          schema = "Listing", 
          data = new ListingData 
             { 
              key = "28ba648c-de24-45d4-a7d9-70f810cf5438", 
              children = new List<object> 
                  { 
                   new Type1 
                    { 
                     body = "Four score and seven years ago...", 
                     parent_id = "2qh3l", 
                     report_count = 0, 
                     name = "c4j6yeh" 
                    }, 
                   new Type3 
                    { 
                     domain = "abc.def.com", 
                     flagged = true, 
                     category = "news", 
                     saved = false, 
                     id = "t3dz0", 
                     created = 1335998011.0 
                    } 
                  } 
             } 
         }; 

    var jsonSerializerSettings = new JsonSerializerSettings 
             { 
              Formatting = Formatting.Indented, 
              TypeNameHandling = TypeNameHandling.Objects 
             }; 

    string serializedResponse = JsonConvert.SerializeObject(response, jsonSerializerSettings); 
    Console.WriteLine(serializedResponse); 
    var roundTrippedResponse = JsonConvert.DeserializeObject<Response>(serializedResponse, jsonSerializerSettings); 
    Assert.That(roundTrippedResponse.data.children.First().GetType(), Is.EqualTo(typeof(Type1))); 
    Assert.That(roundTrippedResponse.data.children.Last().GetType(), Is.EqualTo(typeof(Type3))); 
} 

コンソールに書き込まれる出力は次のとおりです。

{ 
    "$type": "Test.Response, Test", 
    "schema": "Listing", 
    "data": { 
    "$type": "Test.ListingData, Test", 
    "key": "28ba648c-de24-45d4-a7d9-70f810cf5438", 
    "children": [ 
     { 
     "$type": "Test.Type1, Test", 
     "body": "Four score and seven years ago...", 
     "parent_id": "2qh3l", 
     "report_count": 0, 
     "name": "c4j6yeh" 
     }, 
     { 
     "$type": "Test.Type3, Test", 
     "domain": "abc.def.com", 
     "flagged": true, 
     "category": "news", 
     "saved": false, 
     "id": "t3dz0", 
     "created": 1335998011.0 
     } 
    ] 
    } 
} 

だから、あなたが受信した応答を変換することができた場合

は、以下のクラスを考えますJson.NETの予想されるフォーマットのそれと一致するように、これはうまくいくでしょう。

これらをまとめてカスタムのMediaTypeFormatterを作成し、それをReadAsAsync <>()呼び出しに渡す必要があります。

関連する問題