2017-01-09 9 views
3

私はオブジェクト配列と思われるJSONを解析しようとしています。私はJObject.Parseで単純な単一のJSONを解析できますが、これは私に頭痛を与えます。DataGridviewにJSONオブジェクト配列を表示

{ 
"2": { 
    "num": 5, 
    "average": 10, 
    "state": true, 
    "id": 2, 
    "buy": 10, 
    "name": "name" 
}, 
"6": { 
    "num": 5, 
    "average": 10, 
    "state": true, 
    "id": 6, 
    "buy": 20, 
    "name": "name" 
} 
} 

私は考えていたが、かっこの前に数字を処理する方法は知らなかった。それは常に "id"と同じです。

私はこのようなNewtonsoft.Json何かを使用してみました:「タイプは正しくデシリアライズするためにJSON配列(例えば[1,2,3])が必要です」それがいることを言うしかし

List<Items> objlis = (List<Items>)Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(List<Items[]>)); 

+0

あなたのコードはどのように見えますか?あなたはそれが何をすると思いますか?どのように失敗していますか? – ThatBlairGuy

+0

'Dictionary 'を使用しないでください。 [名前がIDのjsonオブジェクトから厳密に型付けされたC#オブジェクトを作成する](https://stackoverflow.com/questions/34213566/create-a-strongly-typed-c-sharp-object-from-json-object-名前付きのID付き/)。 – dbc

答えて

0

に呼び出すことができますJSON配列としてではなく、リストの索引です。しかし、Json.NET maps JSON arrays from and to c# listsのように、List<Items>への逆シリアル化は、例外メッセージで失敗します。タイプでは、正しくデシリアライズするためにJSON配列(例:[1,2,3])が必要です。

var dict = JsonConvert.DeserializeObject<SortedDictionary<int, Items>>(json); 

あなたは、具体的JSONが必要な場合は、リストとして非直列化される:例えば、this questionに示されているようdictionaryDictionary<string, Items>として、あるいはSortedDictionary<int, Items>として

なJSONオブジェクトをデシリアライズするための最も簡単な方法はあります、あなたはマッピングを行うにはcustom JsonConverterを書き込むことができます。

public class ListToDictionaryConverter<T> : JsonConverter where T : class 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(List<T>).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     var list = existingValue as List<T> ?? (List<T>)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator(); 
     if (reader.TokenType == JsonToken.StartArray) 
      serializer.Populate(reader, list); 
     else if (reader.TokenType == JsonToken.StartObject) 
     { 
      var dict = serializer.Deserialize<Dictionary<int, T>>(reader); 
      foreach (var pair in dict) 
       list.SetOrAddAt(pair.Key, pair.Value, default(T)); 
     } 
     else 
     { 
      throw new JsonSerializationException(string.Format("Invalid token {0}", reader.TokenType)); 
     } 
     return list; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var list = (IList<T>)value; 
     writer.WriteStartObject(); 
     for (int i = 0; i < list.Count; i++) 
     { 
      // Omit null values. 
      if (list[i] == default(T)) 
       continue; 
      writer.WritePropertyName(((JValue)i).ToString()); 
      serializer.Serialize(writer, list[i]); 
     } 
     writer.WriteEndObject(); 
    } 
} 

public static class ListExtensions 
{ 
    public static void SetOrAddAt<T>(this IList<T> list, int index, T value, T defaultValue = default(T)) 
    { 
     if (list == null) 
      throw new ArgumentNullException("list"); 
     list.EnsureCount(index + 1, defaultValue); 
     list[index] = value; 
    } 

    public static void EnsureCount<T>(this IList<T> list, int count, T defaultValue = default(T)) 
    { 
     if (list == null) 
      throw new ArgumentNullException("list"); 
     int oldCount = list.Count; 
     if (count > oldCount) 
     { 
      for (int i = oldCount; i < count; i++) 
       list.Add(defaultValue); 
     } 
    } 
} 

次にようにそれを使用します。

var objlis = JsonConvert.DeserializeObject<List<Items>>(json, new ListToDictionaryConverter<Items>()); 

サンプルfiddle

1
var result = JsonConvert.DeserializeObject<List<JsonResult>>(input); 
dataGridView.DataSource = result; 
+0

前に述べたのと同じエラー –

0

あなたはJSONから、次のようなテーブルを構築し、その後、送信側システムは、オブジェクト名があるJSONオブジェクトとしてスパースリストをシリアライズすることを選んだかのように見えますDataGridViewの

List<User> allusers = JsonConvert.DeserializeObject<List<User>>(jsonString); 

public static DataTable MakeDataTable<T>(this IList<T> data) 
     { 
     PropertyDescriptorCollection props = 
     TypeDescriptor.GetProperties(typeof(T)); 
     DataTable table = new DataTable(); 
     for(int i = 0 ; i < props.Count ; i++) 
     { 
     PropertyDescriptor prop = props[i]; 
     table.Columns.Add(prop.Name, prop.PropertyType); 
     } 
     object[] values = new object[props.Count]; 
     foreach (T item in data) 
     { 
     for (int i = 0; i < values.Length; i++) 
     { 
      values[i] = props[i].GetValue(item); 
     } 
     table.Rows.Add(values); 
     } 
     return table;   
    } 
関連する問題