使用 System.Text.Json 反序列化数组 json 对象的嵌套数组

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

我想反序列化 this json file。 json 文件具有以下重复的模式:

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

我正在使用以下代码读取和反序列化 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;
    }
   
}

以上代码导致以下异常

HResult=0x80131500 Message=JSON 值无法转换为 System.Collections.Generic.List`1[Program+Province]。路径:$ |行号:0 | BytePositionInLine:1。 来源=System.Text.Json

我做错了什么?

它永远不会工作,因为 json 字符串没有具有指定名称的属性。

您的 json 字符串必须反序列化到字典中。 试试这个:

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

当你有 JSON 文本数据并且你想为该数据生成 class 模型时,你可以这样生成:在 Visual Studio 2019 年,创建一个新的 class =] 文件,删除该文件中的所有内容,从编辑菜单中,select 特殊粘贴然后粘贴 JSON 为 classes。将生成 classes。在您的情况下,这是生成的 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; }
}

这里有两个解决方案:

第一个( 手动填写数据):

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一个(改变模型结构):

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

使用 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);

            }

访问数据

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

反序列化使用此站点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; }
        }


    }

使用您的代码,再试一次

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