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

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.