2016-10-10 20 views
2

JSONを既知の型またはディクショナリオブジェクトにデシリアライズする際に問題はありませんが、入力が何になるのかわからない場合はどうですか?具体的に私は、キーと値のペアのフラットまたはネストされたセットを表すJSON文字列を受信したことに言及しています:JSON.NETを使用してデシリアライズする

{ 
    foo: 'bar', 
    baz: 42 
} 

または

{ 
    foo: 
    { 
    bar: 42, 
    baz: ['foo', 'bar', 'baz'] 
    } 
} 

しかし、どのような入力がキーでないケースについて値のペアではなく、配列、または他の入れ子になったオブジェクト(配列を含む)のオブジェクトの配列?

[ 
    { foo: 'bar', baz: [ 1, 2, 3 ] }, 
    { foo: 'baz', bar: [ 4, 5, 6 ] } 
] 

私の目標は、上記のいずれかを逆シリアル化してメンバーを繰り返すことができる単一のクラスを持つことです。入力はどのような構造でもかまいませんので、すでに定義したタイプに一致するデータはないと思います。

私はこれを行う方法を見つけることができませんでした。誰でもガイダンスはありますか?

編集:

は、JSON文字列をJToken.Parseやすい十分なようです。有用な次のステップは、メンバーを反復し、JArrayとJObjectを別々に処理することです。

+0

はあなたがダイナミックにdeserialisingと考えたことがありますか? http://stackoverflow.com/questions/4535840/deserialize-json-object-into-dynamic-object-using-json-net –

+0

はい、私は入力が配列のない場合に動作するようには思えません。キー。 – joelc

+0

キーのない配列はどういう意味ですか? – Abion47

答えて

3

Json.Netには既に説明しているとおり、LINQ-to-JSON API(JTokens)です。以下は、これを使用して任意のJSONを解析し、メンバーを反復処理する例です。 JSONは任意の深さにネストすることができるので、再帰的なメソッドが必要であることに注意してください。ここで

using Newtonsoft.Json.Linq; 
public class Program 
{ 
    public static void Main(string[] args) 
    { 
     string json1 = @" 
     { 
      ""foo"": { ""bar"": 42, ""baz"": [ ""a"", ""b"", ""c"" ] } 
     }"; 
     DeserializeAndDump(json1, "example 1"); 

     string json2 = @" 
     [ 
      { ""foo"": ""bar"", ""baz"": [ 1, 2, 3 ] }, 
      { ""foo"": ""baz"", ""bar"": [ 4, 5, 6 ] } 
     ]"; 
     DeserializeAndDump(json2, "example 2"); 
    } 

    public static void DeserializeAndDump(string json, string label) 
    { 
     Console.WriteLine("---- " + label + " ----"); 
     JToken token = JToken.Parse(json); 
     DumpJToken(token); 
     Console.WriteLine(); 
    } 

    public static void DumpJToken(JToken token, string indent = "") 
    { 
     if (token.Type == JTokenType.Object) 
     { 
      Console.WriteLine(indent + "begin object"); 
      foreach (JProperty prop in token.Children<JProperty>()) 
      { 
       Console.WriteLine(indent + " " + prop.Name + ":"); 
       DumpJToken(prop.Value, indent + " "); 
      } 
      Console.WriteLine(indent + "end object"); 
     } 
     else if (token.Type == JTokenType.Array) 
     { 
      Console.WriteLine(indent + "begin array"); 
      foreach (JToken child in token.Children()) 
      { 
       DumpJToken(child, indent + " "); 
      } 
      Console.WriteLine(indent + "end array"); 
     } 
     else 
     { 
      Console.WriteLine(indent + token.ToString() + " (" + token.Type.ToString() + ")"); 
     } 
    } 
} 

は、上記の出力である:

---- example 1 ---- 
begin object 
    foo: 
    begin object 
     bar: 
     42 (Integer) 
     baz: 
     begin array 
      a (String) 
      b (String) 
      c (String) 
     end array 
    end object 
end object 

---- example 2 ---- 
begin array 
    begin object 
    foo: 
     bar (String) 
    baz: 
     begin array 
     1 (Integer) 
     2 (Integer) 
     3 (Integer) 
     end array 
    end object 
    begin object 
    foo: 
     baz (String) 
    bar: 
     begin array 
     4 (Integer) 
     5 (Integer) 
     6 (Integer) 
     end array 
    end object 
end array 

フィドル:https://dotnetfiddle.net/dfk0sj

+1

ブライアンは完璧な例をありがとうございました。私は本当にあなたがこれを行うのにかかった時間を感謝します。 – joelc

+1

問題ありません。お役に立てて嬉しいです。 –

関連する問題