【问题标题】:Parse JSON data from file using C# [closed]使用 C# 从文件中解析 JSON 数据 [关闭]
【发布时间】: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 和/或解析为对象。

标签: c# json parsing


【解决方案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,我需要提取此对象内的数组的日期,我该怎么办?
  • 谢谢,它适用于所有对象:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 2012-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多