1

This is my JSON object and C# class

   {
        "header": [
            "id",
            "name",
            "address"
        ],
        "rows": [
            [
                "ee1e9edd-a06b-3f8c-97f1-62878d04540d",
                "John Doe",
                "test address 1234"
            ],
            [
                "ee1e9edd-a06b-3f8c-97f1-62878d04540d",
                "Jane Rock",
                "test address 12345"
            ]
        ]
    }

C# class

    public class Student
    {
        public string id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
    }

is that possible to convert JSON into C# class list using JsonConvert or any other library without using loop?

8
  • 3
    That is not valid json, secondly paste your valid json into a json to C# converter, then the answer becomes yes, with a little bit of massaging Commented Aug 25, 2021 at 6:07
  • That class cannot be used with that JSON. At the very least, you need a different class with List<List<string>> rows Commented Aug 25, 2021 at 6:11
  • 4
    dotnetfiddle.net/piqBpZ Commented Aug 25, 2021 at 6:16
  • 1
    I would replace [<student details>] with {<student details>} Commented Aug 25, 2021 at 6:21
  • If your are using Visual Studio, copy the json content and use Menu: Edit -> Paste Special -> Paste JSON as Classes to create the classes Commented Aug 25, 2021 at 6:56

2 Answers 2

1

The conversion is pretty straightforward with Json.NET's JObject and Linq:

var students = JObject.Parse(json)["rows"] // Parse the JSON and get the "rows" property
    .Values<string[]>() // Get the property values as string arrays
    .Select(arr => new Student() { // Convert each string array to a Student object
        id = arr[0],
        name = arr[1],
        address = arr[2]
    }).ToList(); // Convert the IEnumerable<Student> to a List<Student>
Sign up to request clarification or add additional context in comments.

Comments

0

If you have multiple json definitions that have the same headers/rows layout you could use this custom converter for the Newtonsoft.Json library.

Usage:

var input = "{\"header\":[\"id\",\"name\",\"address\"],\"rows\":[[\"ee1e9edd-a06b-3f8c-97f1-62878d04540d\",\"John Doe\",\"test address 1234\"],[\"ee1e9edd-a06b-3f8c-97f1-62878d04540d\",\"Jane Rock\",\"test address 12345\"]]}";
         
var studens = JsonConvert.DeserializeObject<List<Student>>(input, new MyConverter<Student>());
foreach (var student in students)
{
    Console.WriteLine(student.name);
}

The converter looks like this:

public class MyConverter<T> : JsonConverter where T : new()
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // Not required.
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        reader.Read(); // Read StartObject token.
        var mapping = GetMapping(reader);
        var result = GetObjects(reader, mapping);
        reader.Read(); // Read EndObject token.
        return result;
    }

    private Dictionary<int, string> GetMapping(JsonReader reader)
    {
        Dictionary<int, string> mapping = new();
        
        // Advance to the first header definition.
        reader.Read(); // Read PropertyName token (should be 'headers').
        reader.Read(); // Read StartArray token.
                    
        int index = 0;
        do 
        {
            index++;
            mapping[index] = reader.Value.ToString();
            reader.Read(); // Advance to next array element.
        }
        while(reader.TokenType != JsonToken.EndArray);
        reader.Read(); // Read EndArray token.
        
        return mapping;
    }
    
    private List<T> GetObjects(JsonReader reader, Dictionary<int, string> mapping)
    {   
        List<T> result = new();
        
        // Advance to the first row definition.
        reader.Read(); // Read PropertyName token (should be 'rows').
        reader.Read(); // Read StartArray token.
        do 
        {   
            result.Add(GetObject(reader, mapping));
        }
        while(reader.TokenType != JsonToken.EndArray);      
        reader.Read(); // Read EndArray token.
        
        return result;
    }
    
    private T GetObject(JsonReader reader, Dictionary<int, string> mapping)
    {
        // The object is an array in json.
        reader.Read(); // Read StartArray token.
        
        int index = 0;
        T result = new();       
        do
        {
            index++;
            var propertyToFind = mapping[index];
            // Set the value to a property with matching name if it exists.
            result.GetType().GetProperty(propertyToFind)?.SetValue(result, reader.Value);
            reader.Read(); // Advance to next array element.
        }
        while(reader.TokenType != JsonToken.EndArray);
        reader.Read(); // Read EndArray token.
        
        return result;
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.