3

Im trying to parse JSON which is I believe object array. I can parse simple single JSON with JObject.Parse but this one gives me headache.

{
"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"
 }
}

I had idea but dont know how to deal with numbers before bracket. Its always the same as "id".

I tried to use Newtonsoft.Json something like this:

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

However it says that "the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly."

2

3 Answers 3

1

You can built table like following from Json and then call to 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;        
    }
Sign up to request clarification or add additional context in comments.

Comments

0

It looks as though the sending system chose to serialize a sparse list as a JSON object where the object names are the list indices, rather than as a JSON array. But Json.NET maps JSON arrays from and to c# lists so your deserialization to List<Items> fails with the exception message the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

The simplest way to deserialize such a JSON object is as a dictionary such as Dictionary<string, Items> or SortedDictionary<int, Items> as is shown in this question, e.g.:

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

If you specifically require the JSON to be deserialized as a list, you can write a custom JsonConverter to do the mapping:

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);
        }
    }
}

Then use it like:

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

Sample fiddle.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.