7

I'm new to JSON.NET, and I need help to deserialize the following JSON

{
   "items": [
      [10, "file1", "command 1"],
      [20, "file2", "command 2"],
      [30, "file3", "command 3"]
   ]
}

to this

IList<Item> Items {get; set;}

class Item
{
   public int    Id      {get; set}
   public string File    {get; set}
   public string Command {get; set}
}

The content in the JSON is always in the same order.

7
  • what's you problem with JSON.NET ? Commented Apr 17, 2015 at 9:54
  • But if I try to deserialize to List<Item>, JSON.NET complains that it cannot populate array Commented Apr 17, 2015 at 9:59
  • ok let me try with this code please wait. Commented Apr 17, 2015 at 10:01
  • yeh i found the problem. you can't deserialize this json string to LIST<ITEM>. Commented Apr 17, 2015 at 10:04
  • 1
    You can only deserialize this string to public class Rootobject { public object[][] items { get; set; } } Commented Apr 17, 2015 at 10:09

3 Answers 3

13

You can use a custom JsonConverter to convert each child array in the JSON to an Item. Here is the code you would need for the converter:

class ItemConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Item));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JArray array = JArray.Load(reader);
        return new Item
        {
            Id = (int)array[0],
            File = (string)array[1],
            Command = (string)array[2]
        };
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

With the above converter, you can deserialize into your classes easily as demonstrated below:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
           ""items"": [
              [10, ""file1"", ""command 1""],
              [20, ""file2"", ""command 2""],
              [30, ""file3"", ""command 3""]
           ]
        }";

        Foo foo = JsonConvert.DeserializeObject<Foo>(json, new ItemConverter());

        foreach (Item item in foo.Items)
        {
            Console.WriteLine("Id: " + item.Id);
            Console.WriteLine("File: " + item.File);
            Console.WriteLine("Command: " + item.Command);
            Console.WriteLine();
        }
    }
}

class Foo
{
    public List<Item> Items { get; set; }
}

class Item
{
    public int Id { get; set; }
    public string File { get; set; }
    public string Command { get; set; }
}

Output:

Id: 10
File: file1
Command: command 1

Id: 20
File: file2
Command: command 2

Id: 30
File: file3
Command: command 3

Fiddle: https://dotnetfiddle.net/RXggvl

Sign up to request clarification or add additional context in comments.

Comments

0

For deserialization your JSON should be like this

{
   "items": [
      {Id: 10, File: "file1", Command: "command 1"},
      {Id: 20, File: "file2", Command: "command 2"},
      {Id: 30, File: "file3", Command: "command 3"}
   ]
}

This will map the variables Id, File and Command to properties Id, File and Command respectively during deserialization

You can deserialize it using the following code

public List<Item> DeserializeJSON(string jsonString)
{
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<Item>)); 
    MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); 
    var obj = (List<Item>)ser.ReadObject(stream);
    return obj;
}

2 Comments

Yes, if the JSON is formated this way, it is no problems. But now it isn't. Is it any way to make JSON.NET to convert the data from array to the properties?
@magol, since this is a string and your class is not complex, it is possible to parse the string and store it in the list collection manually without using a serializer. But this type of solution will not be generic and it will be specific for this json string only
0

You can do this by using an intermediate type to capture the conversion from Json and the map that to your Item class afterwards. So first we have the intermediate class:

public class IntermediateType
{
    public object[][] items { get; set; }
}

And now we can get your results like this:

var json = "{\"items\": [ [10, \"file1\", \"command 1\"], [20, \"file2\", \"command 2\"], [30, \"file3\", \"command 3\"] ]}";

var result = JsonConvert
    .DeserializeObject<IntermediateType>(json)
    .items
    .Select(o => new Item
    {
        Id = int.Parse(o[0].ToString()),
        File = (string)o[1],
        Command = (string)o[2]
    });

1 Comment

The problem with this approach is that if there are data types like doubles, there's cases that the DeserializeObject will change what should be a double into an int. Then when we try casting the object to double, we get cast exceptions.

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.