在 c# 中解析 json 文件以进入所有部分和属性

Parsing json file in c# to get into all sections and properties

==========更新

因此,在尝试正确表达问题时,我误导了响应者,没有给我我需要的答案。抱歉,让我试着澄清一下。

我需要能够循环浏览一个 json 文件,该文件不像我在 OP 中指出的那样结构化,它更加随机。 OP 文件没有很好地传达这一点。

让我尝试描述更接近我将要获取的文件的内容。前两个级别将是固定的,我将它们称为 LevelA 和 LevelB。但是 LevelB 中的属性可以是任意一对随机数据。这是一个更好的 json 文件示例:

{
  "LevelA": {
    "LevelB": [
      {
        "EmpName": "John",
        "EmpGender": "Male",
        "Age": "25"
      },
      {
        "FavoriteFood": "Beer",
        "BaseballTeam": "Kansas City Royals"
      },
      {
        "Red": "10",
        "Blue": "40",
        "White: "True"
      }
    ]
  }
}

假设我需要写出以下内容给控制台:

A LevelB entry has these properties:
Property: EmpName, Value: John
Property: EmpGender, Value: Male
Property: Age, Value: 25

A LevelB entry has these properties:
Property: FavoriteFood, Value: Beer
Property: BaseballTeam, Value: Kansas City Royals

A LevelB entry has these properties:
Property: Red, Value: 10
Property: Blue, Value: 40
Property: White, Value: True

这可能没有意义,但是,我需要找到一种方法来做到这一点,我需要这些知识。我很欣赏关于使用模型的答案,但我没有看到一种使用模型的方法,而不会使我认为应该是一项简单的任务复杂化。虽然显然不够简单,但我无法弄清楚。 :)

==========

C#、VS 2019、.NET 框架控制台测试应用程序。我想做一些简单的事情,但找不到正确的语法。 我有一个具有以下结构的 json 文件。我想遍历下面的每个员工并获取其属性(姓名、性别等...):

{
  "Company": {
    "Employees": [
      {
        "EmpName": "John",
        "EmpGender": "Male",
        "Age": "25"
      },
      {
        "EmpName": "Mary",
        "EmpGender": "Female"
      },
      {
        "EmpName": "Bill",
        "Age": "30"
      }
    ]
  }
}

第一个问题是哪个包可以完成这项工作?我已经安装了 Microsoft.Extensions.Configuration.Json 和 System.Configuration.ConfigurationManager,但我很难正确地使用语法。这些包是否适合使用?我决定使用它们,因为我认为我可以通过 ConfigurationBuilder 加载文件,并且 GetSection and/or GetChildren 方法会帮助我。我可以加载文件,但我不知道如何使用这些方法来满足我的需求。

其次,我不想为此建立模型,我只想要数据。如果我可以将每个员工都放入字典中,我可以对其进行分析,这会让我继续前进。感谢您的任何建议。

你可以在.net core

中使用built-in JSON library
using System.Text.Json;

添加以下模型定义

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

    public class Company
    {
        public Employee[] Employees { get; set; }
    }

    public class Employee
    {
        public string EmpName { get; set; }
        public string EmpGender { get; set; }
        public string Age { get; set; }
    }

像下面这样反序列化你的对象

string jsonData = File.ReadAllText("data.json");
Rootobject ob = JsonSerializer.Deserialize<Rootobject>(jsonData);

现在你有 ob 在你的 C# 中将你的 JSON 表示为 C# 对象

I don't want to build a model for this

如果您使用 Visual Studio,您可以自动生成您的 JSON 所需的模型 类,如所述 here 以上模型由 [=27= 自动生成]

为什么要求不建模型?在我看来,这是最简单的方法,如果由于 JSON 更改而需要扩展,您可以轻松地在代码中进行调整。我在这里粘贴了一个使用 System.Text.Json 命名空间的示例代码(由于它是内置的,因此不需要其他包)。

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

namespace jsontest
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = "{ \"Company\": { \"Employees\": [{ \"EmpName\": \"John\", \"EmpGender\": \"Male\", \"Age\": \"25\" }, { \"EmpName\": \"Mary\", \"EmpGender\": \"Female\" }, { \"EmpName\": \"Bill\", \"Age\": \"30\" }]}}";

            var processedInput = JsonSerializer.Deserialize<Company>(input);
            
            foreach (var item in processedInput.Peoples.PeopleList)
            {
                Console.WriteLine($"{item.Name} - {item.Gender} - {item.Age}");
            }
        }
    }

    public class Employee
    {
        [JsonPropertyName("EmpName")]
        public string Name { get; set; }

        [JsonPropertyName("EmpGender")]
        public string Gender { get; set; }

        [JsonPropertyName("Age")]
        public string Age { get; set; }
    }

    public class Employees
    {
        [JsonPropertyName("Employees")]
        public List<Employee> PeopleList { get; set; }
    }

    public class Company
    {
        [JsonPropertyName("Company")]
        public Employees Peoples { get; set; }
    }
}

更新后更新: 奇怪为什么要这样把数据存到JSON里。我写了一个快速代码,它使用正则表达式和一些内置函数来解析文本。最终结果与您希望的相似。代码有点长,只是为了方便大家理解,我加了一些注释。

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

namespace jsontest
{
    class Program
    {
        static void Main(string[] args)
        {
            List<List<ListItem>> result = new List<List<ListItem>>();

            string input = "{ \"Company\": { \"Employees\": [{ \"EmpName\": \"John\", \"EmpGender\": \"Male\", \"Age\": \"25\" }, { \"EmpName\": \"Mary\", \"EmpGender\": \"Female\" }, { \"EmpName\": \"Bill\", \"Age\": \"30\" }]}}";

            // Remove new lines, so input will become one single line
            input = input.Replace(Environment.NewLine, " ");

            // 1. group is the group name (in this case Employees)
            // 2. group is the content after group name
            string pattern1 = @"[{].+[{](.+)[\[](.+)[\]]";

            foreach (System.Text.RegularExpressions.Match m in System.Text.RegularExpressions.Regex.Matches(input, pattern1))
            {
                // groupName -> "Employees":
                string groupName = m.Groups[1].Value;

                // groupName -> Employees
                groupName = groupName.Substring(0, groupName.LastIndexOf("\""));
                groupName = groupName.Substring(groupName.IndexOf("\"") + 1);

                // contentList -> { "EmpName": "John", "EmpGender": "Male", "Age": "25" }, { "EmpName": "Mary", "EmpGender": "Female" }, { "EmpName": "Bill", "Age": "30" }
                string contentList = m.Groups[2].Value;

                // Split the line onto more lines where "}," characters
                // { "EmpName": "John", "EmpGender": "Male", "Age": "25"
                // { "EmpName": "Mary", "EmpGender": "Female"
                // { "EmpName": "Bill", "Age": "30" }
                string[] contentItems = contentList.Split("},");

                foreach (var item in contentItems)
                {
                    // Check every group and store them in separate list
                    result.Add(new List<ListItem>());

                    string[] keys = item.Split(",");

                    foreach (var key in keys)
                    {
                        // Check every Key-Value pair and store their value in the current list
                        string pattern2 = "[\"](.+)[:].[\"](.+)[\"]";
                        foreach (System.Text.RegularExpressions.Match m2 in System.Text.RegularExpressions.Regex.Matches(key, pattern2))
                        {
                            result[result.Count - 1].Add(new ListItem() { Property = groupName, Key = m2.Groups[1].Value.Substring(0, m2.Groups[1].Value.Length - 1), Value = m2.Groups[2].Value });
                        }
                    }
                }
            }

            for (int i = 0; i < result.Count; i++)
            {
                for (int j = 0; j < result[i].Count; j++)
                {
                    if (j == 0)
                        Console.WriteLine($"A {result[i][j].Property} entry has these properties:");

                    Console.WriteLine($"Proprty: {result[i][j].Key}, Value: {result[i][j].Value}");
                }
            }
        }
    }

    class ListItem
    {
        public string Property { get; set; }
        public string Key { get; set; }
        public string Value { get; set; }
    }


}

这段代码的输出是:

A Employees entry has these properties:
Proprty: EmpName, Value: John
Proprty: EmpGender, Value: Male
Proprty: Age, Value: 25
A Employees entry has these properties:
Proprty: EmpName, Value: Mary
Proprty: EmpGender, Value: Female
A Employees entry has these properties:
Proprty: EmpName, Value: Bill
Proprty: Age, Value: 30

如果你不想创建模型,而得到一个List<Dictionary<string,string>>,你可以使用自定义模型绑定,这里是一个演示: 自定义绑定器:

public class CustomBinder:IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
            var model = new List<Dictionary<string, string>>();
            using (var reader = new StreamReader(bindingContext.HttpContext.Request.Body))
            {
                var body = reader.ReadToEndAsync();

                var mydata = JsonConvert.DeserializeObject<JObject>(body.Result);
                var s = mydata["Company"]["Employees"].ToString();
                var list=JsonConvert.DeserializeObject<List<JObject>>(s);
                foreach (var jobj in list) {
                    Dictionary<string, string> d = new Dictionary<string, string>();
                    foreach (var x in jobj)
                    {
                        string name = x.Key;
                        string value = x.Value.ToString();
                        d.Add(x.Key, x.Value.ToString());
                    }
                    model.Add(d);
                }

            }

            bindingContext.Result = ModelBindingResult.Success(model);
            return Task.CompletedTask;
        }
    }

操作:

public void TestJson1([ModelBinder(BinderType = typeof(CustomBinder))] List<Dictionary<string, string>> jsondata)
        {

        }

结果: