Using System.Text.Json to deserialize nested array of array json object

1

I would like to deserialize this json file. The json file has the following pattern that repeats itself:

{
    "Province": {
        "District": {
            "Sector": {
                "Cell": [
                    "Village1",
                    "Village2",
                    "Village3",
                    "Village4"
                ]
            }
        }
    }
}

I am using the following code to read and deserialized the json

using System;
using System.Collections.Generic;
using System.Text.Json;

class Program
{
    public class Province {
        public string Name { get; set; }
        public ICollection<District> Districts { get; set; }
    }
    public  class District {
        public string Name { get; set; }
        public ICollection<Sector> Sectors { get; set; }

    }
    public class Sector {
        public string Name { get; set; }
        public ICollection<Cell> Cells { get; set; }
    }
    public class Cell {
        public string Name { get; set; }
        public ICollection<Village> Villages { get; set; }
    }
    public class Village {
        public string Name { get; set; }
    }
    static void Main(string[] args) {
        string json = DownloadJsonData();
        var provinces = JsonSerializer.Deserialize<List<Province>>(json);
    Console.WriteLine(provinces[0].Name);
    }
    private static string DownloadJsonData() {
        using var webClient = new System.Net.WebClient();
        string result = webClient.DownloadString("https://raw.githubusercontent.com/ngabovictor/Rwanda/master/data.json");
        return result;
    }
   
}

The above code results in the following exception

HResult=0x80131500 Message=The JSON value could not be converted to System.Collections.Generic.List`1[Program+Province]. Path: $ | LineNumber: 0 | BytePositionInLine: 1. Source=System.Text.Json

What I am doing wrong?

c#
json
asp.net-core
.net-core
system.text.json
asked on Stack Overflow Jan 25, 2021 by bherve1998 • edited Apr 3, 2021 by dbc

4 Answers

1

It will never work because the json string has no properties with the specified names.

Your json string must be deserialized into a dictionary. Try this:

static void Main(string[] args)
    {
        string json = DownloadJsonData();
        var provinces = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string[]>>>>>(json);
        foreach (var province in provinces)
        {
            Console.WriteLine("Province: {0}", province.Key);
            var districts = province.Value;
            foreach (var district in districts)
            {
                Console.WriteLine("\tDistrict: {0}", district.Key);
                var sectors = district.Value;
                foreach (var sector in sectors)
                {
                    Console.WriteLine("\t\tSector: {0}", sector.Key);
                    var cells = sector.Value;
                    foreach (var cell in cells)
                    {
                        Console.WriteLine("\t\t\tCell: {0}", cell.Key);
                        var values = cell.Value;
                        foreach (var value in values)
                        {
                            Console.WriteLine("\t\t\t\t{0}", value);
                        }
                    }
                }
            }
        }
        Console.ReadKey();
    }

    private static string DownloadJsonData()
    {
        using var webClient = new System.Net.WebClient();
        string result = webClient.DownloadString("https://raw.githubusercontent.com/ngabovictor/Rwanda/master/data.json");
        return result;
    }
answered on Stack Overflow Jan 25, 2021 by Quetzal Rivera
1

When you have JSON text data and you want to generate class model for that data, you can generate by this: In Visual Studio 2019, create a new class file, delete all content in that file, from the Edit menu, select Special Paste then Paste JSON as classes. The classes will be generated. In your case, here is the generated classes:

public class Rootobject
{
    public Province Province { get; set; }
}

public class Province
{
    public District District { get; set; }
}

public class District
{
    public Sector Sector { get; set; }
}

public class Sector
{
    public string[] Cell { get; set; }
}
answered on Stack Overflow Jan 25, 2021 by Nam Pham
0

Here are two solutions:

First one( Fill in data manually):

static void Main(string[] args) {
        string json = DownloadJsonData();
        var mydata = JsonConvert.DeserializeObject<JObject>(json);
        List<string> l= JsonConvert.DeserializeObject<List<string>>(mydata["Province"]["District"]["Sector"]["Cell"].ToString());
                List<Village> vs = new List<Village>();
                foreach (var str in l) {
                    vs.Add(new Village { Name = str });
                }
        var model = new Province();
        model.Districts = new List<District> { new District { Sectors = new List<Sector> { new Sector { Cells = new List<Cell> { new Cell { Villages = vs } } } } } };
        Console.WriteLine(model.Name);
    }

2.Second One(Change the model structure):

public class Province1
    {
        public District1 District { get; set; }
    }
    public class District1 {
        public Sector1 Sector { get; set; }
    }
    public class Sector1
    {
        public List<string> Cell { get; set; }
    }
static void Main(string[] args) {
        string json = DownloadJsonData();
        var mydata = JsonConvert.DeserializeObject<JObject>(body.Result);
        var mydata1 = JsonConvert.DeserializeObject<Province1>(mydata["Province"].ToString()); 
        Console.WriteLine(mydata1.Name);
    }
answered on Stack Overflow Jan 25, 2021 by Yiyi You
0

using IHttpClientFactory

var httpclient = _httpClientFactory.CreateClient();
            var response = await httpclient.GetAsync("https://raw.githubusercontent.com/ngabovictor/Rwanda/master/data.json");

            if (response.IsSuccessStatusCode)
            {
                var responseData = await response.Content.ReadAsStringAsync();
                var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
                var resultData = JsonSerializer.Deserialize<Root>(responseData, options);

                return (true, resultData, responseData);

            }

for access data

            var datasExample = resultData.East.Bugesera.Gashora.Biryogo;

for deserialize use this site Convert Json to C# classes

public class ClassExample
    {

        // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
        public class Gashora
        {
            public List<string> Biryogo { get; set; }
            public List<string> Kabuye { get; set; }
            public List<string> Kagomasi { get; set; }
            public List<string> Mwendo { get; set; }
            public List<string> Ramiro { get; set; }
        }

        public class Bugesera
        {
            public Gashora Gashora { get; set; }
        }

        public class East
        {
            public Bugesera Bugesera { get; set; }
        }

        public class Root
        {
            public East East { get; set; }
        }


    }

using your code, try again with this

public class Sector    {
    public List<string> Cell { get; set; } 
}

public class District    {
    public Sector Sector { get; set; } 
}

public class Province    {
    public District District { get; set; } 
}

public class Root    {
    public Province Province { get; set; } 
}

     static void Main(string[] args) {
            string json = DownloadJsonData();
            var provinces = JsonSerializer.Deserialize<Root>(json);
        }
answered on Stack Overflow Jan 25, 2021 by Daniel • edited Jan 25, 2021 by Daniel

User contributions licensed under CC BY-SA 3.0