使用 C# 从文件中解析 JSON 数据 [关闭]

Posted

技术标签:

【中文标题】使用 C# 从文件中解析 JSON 数据 [关闭]【英文标题】:Parse JSON data from file using C# [closed] 【发布时间】:2020-06-04 00:05:39 【问题描述】:

我正在尝试解析一个 json 文件,但这有点难。我正在使用 Visual Studio 2019。

我需要从文件中获取一些数据。

这是我需要提取的 Json 文件数据:


    "Id": "92cb6271-005e-48e9-a319-a606b8b6e1ef",
    "DefaultPosition": 
        "PositionId": "35ed169a-1208-4d8a-8faa-d2627d5790ed",
        "EntityDetails": 
            "DateCreated": "2019-09-17T15:25:52.4942161-03:00",
            "DateModified": "2019-09-17T15:45:28.896274-03:00",
            "CreatedBy": 
                "Id": "1abb5047-8580-4be1-909d-41138035e4c9",
                "ItemDisplayText": "Laurete Araujo",
                "ItemType": "Users"
            ,
            "ModifiedBy": 
                "Id": "1abb5047-8580-4be1-909d-41138035e4c9",
                "ItemDisplayText": "Laurete Araujo",
                "ItemType": "Users"
            ,
            "Owner": 
                "Id": "1abb5047-8580-4be1-909d-41138035e4c9",
                "ItemDisplayText": "Laurete Araujo",
                "ItemType": "Users"
            
        ,
        "NameComponents": 
        "FullName": "ABRAHÃO DOS SANTOS",
        "FamilyName": "SANTOS",
        "FirstName": "ABRAHÃO DOS"
        ,
        "MaritalStatus": 
        "Id": "97d7a9dd-a7c4-4076-829c-7ec63b0e3fe7",
        "DisplayTitle": "Marital Status",
        "ItemDisplayText": "Married",
        "ItemType": "LookupListEntries"
        

这是我尝试使用的 C# 代码,但它给我带来了问题:

public void JsonParser(string file) 

    string fullname;
    string gender;
    string nationality;
    string maritalstatus;

    var json = System.IO.File.ReadAllText(file);

    var objects = Newtonsoft.Json.Linq.JArray.Parse(json); // parse as array 

    foreach (JObject root in objects)
    
        foreach (KeyValuePair<String, JToken> app in root)
        
            var appName = app.Key;
            fullname = (String)app.Value["FullName"];

            if (app.Key == "Gender") 
            
                gender = (String)app.Value["ItemDisplayText"];
                Console.WriteLine(gender);
            

            Console.WriteLine(fullname);
            Console.WriteLine("\n");
        
    

当我运行代码并尝试从我要提取数据的位置导入文件时,出现以下错误:

Newtonsoft.Json.JsonReaderException: '从 JsonReader 读取 JArray 时出错。当前 JsonReader 项不是数组:StartObject。路径'',第 1 行,位置 1。'

谢谢!

【问题讨论】:

根据jsonlint.com,您发布的JSON 字符串无效。请发布正确的JSON 字符串 您可能会发现反序列化 JSON 然后将所需数据作为常见的普通对象属性访问更简单。在这里对过去的问题进行 30 分钟的适当研究将为您提供此类任务的大部分基础知识。 @RahulSharma,对不起,我刚刚剪掉了一段代码。 JSON 文件具有有效的 JSON。对不起 @Shoy 如果您无法发布整个JSON 字符串,则粘贴一个有效字符串块。 从我看到的 json 不是一个数组。请发布 json 和/或解析为对象。 【参考方案1】:

由于文件以 作为根,这意味着您不能使用 JArray,因为它不是数组。它是一个单一的对象。相反,您应该这样做:

        var root = Newtonsoft.Json.Linq.JObject.Parse(json);
        foreach (KeyValuePair<String, JToken> app in root)
        
            var appName = app.Key;
            fullname = (String)app.Value["FullName"];

            if (app.Key == "Gender")
            
                gender = (String)app.Value["ItemDisplayText"];
                Console.WriteLine(gender);
            

            Console.WriteLine(fullname);
            Console.WriteLine("\n");

        

编辑 - 更好的答案

这里更好的答案是,如果这不是动态的,请声明它将反序列化的 c# 类,然后您可以像这样运行所有这些:

public class CreatedBy

    public string Id  get; set; 
    public string ItemDisplayText  get; set; 
    public string ItemType  get; set; 


public class ModifiedBy

    public string Id  get; set; 
    public string ItemDisplayText  get; set; 
    public string ItemType  get; set; 


public class Owner

    public string Id  get; set; 
    public string ItemDisplayText  get; set; 
    public string ItemType  get; set; 


public class EntityDetails

    public DateTime DateCreated  get; set; 
    public DateTime DateModified  get; set; 
    public CreatedBy CreatedBy  get; set; 
    public ModifiedBy ModifiedBy  get; set; 
    public Owner Owner  get; set; 


public class NameComponents

    public string FullName  get; set; 
    public string FamilyName  get; set; 
    public string FirstName  get; set; 


public class MaritalStatus

    public string Id  get; set; 
    public string DisplayTitle  get; set; 
    public string ItemDisplayText  get; set; 
    public string ItemType  get; set; 


public class DefaultPosition

    public string PositionId  get; set; 
    public EntityDetails EntityDetails  get; set; 
    public NameComponents NameComponents  get; set; 
    public MaritalStatus MaritalStatus  get; set; 


public class RootObject

    public string Id  get; set; 
    public DefaultPosition DefaultPosition  get; set; 

...

  var root = JsonConvert.DeserializeObject<RootObject>(json);

  var fullname = root.DefaultPosition.NameComponents.FullName;

【讨论】:

谢谢你,丹尼尔!但现在出现了这个错误:System.InvalidOperationException: 'Cannot access child value on Newtonsoft.Json.Linq.JValue.'你知道我该如何解决吗?谢谢! @Shoy 我将答案更新为比尝试直接解析更好的答案 - 但它只有在它不是动态的情况下才有效。【参考方案2】:

您的 json 存在问题,它不是数组,您正在尝试将其解析为 jarray,

这就是你的 json 的样子

[
    
      "Id": "92cb6271-005e-48e9-a319-a606b8b6e1ef",
      "DefaultPosition": 
        "PositionId": "35ed169a-1208-4d8a-8faa-d2627d5790ed",
        "EntityDetails": 
          "DateCreated": "2019-09-17T15:25:52.4942161-03:00",
          "DateModified": "2019-09-17T15:45:28.896274-03:00",
          "CreatedBy": 
            "Id": "1abb5047-8580-4be1-909d-41138035e4c9",
            "ItemDisplayText": "Laurete Araujo",
            "ItemType": "Users"
          ,
          "ModifiedBy": 
            "Id": "1abb5047-8580-4be1-909d-41138035e4c9",
            "ItemDisplayText": "Laurete Araujo",
            "ItemType": "Users"
          ,
          "Owner": 
            "Id": "1abb5047-8580-4be1-909d-41138035e4c9",
            "ItemDisplayText": "Laurete Araujo",
            "ItemType": "Users"
          
        ,
        "NameComponents": 
          "FullName": "ABRAHÃO DOS SANTOS",
          "FamilyName": "SANTOS",
          "FirstName": "ABRAHÃO DOS"
        ,
        "MaritalStatus": 
          "Id": "97d7a9dd-a7c4-4076-829c-7ec63b0e3fe7",
          "DisplayTitle": "Marital Status",
          "ItemDisplayText": "Married",
          "ItemType": "LookupListEntries"
        
      
    
  ]

或者如果你想得到确切的值而不把它当作数组,那么你可以使用这个

public static void JsonParser(string file)

    string fullname;
    string gender;
    string nationality;
    string maritalstatus;

    var json = System.IO.File.ReadAllText(file);

    var objects = JObject.Parse(json);

    fullname = (string)objects["DefaultPosition"]["NameComponents"]["FullName"];
    Console.WriteLine(fullname);
    Console.WriteLine("\n");

但理想的方法应该是创建一个具有相同结构并反序列化到该特定对象的模型。

【讨论】:

是的,它不是数组,但是我无法编辑json文件,这不是我想做的,我想修改C#代码来读取文件。 @Shoy 您可以检查编辑以获取更新的答案 嘿,Kannangokul,我需要提取此对象内的数组的日期,我该怎么办? 谢谢,它适用于所有对象:)

以上是关于使用 C# 从文件中解析 JSON 数据 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 中的 JSON 对象中提取数组(新

c#生成的Json如何用python解析

使用 C# 解析 JSON 文本文件

如何在 C# 中解析复杂的 JSON?最终我想在 DataGridView 中显示结果 [关闭]

JSON解析数组C# [关闭]

在 c# (Unity) 中解析 JSON 文件