【问题标题】:De-Serialize multi line JSON to C# object将多行 JSON 反序列化为 C# 对象
【发布时间】:2023-03-12 16:38:01
【问题描述】:
 {"ItemName":"8","Id":1}
 {"ItemName":"9","Id":2}

我正在从 blob 读取 json 文件,每一行都有上述格式,行甚至没有用逗号分隔,而且文件中也没有方括号。

当我尝试在 jsontextreader 中将 SupportMultipleContent 设置为 true 时,我得到以下异常:

 Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ValueDTO]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'ItemName', line 1, position 12.

或者,如果无法解析此类 json,那么我将如何在 azure 中配置数据工厂以使文件具有正确的 json 格式。

代码:

using (var sr = new StreamReader(stream))
{
    using (var jsonTextReader = new JsonTextReader(sr))
    {
        jsonTextReader.SupportMultipleContent = true;
        while (jsonTextReader.Read())
        {
            var data = serializer.Deserialize<T>(jsonTextReader);
            result.Add(data);
        }

    }
}

Json 没有明确的 \n 字符

【问题讨论】:

  • 在那种格式中,它不是一个对象;您需要分别解析每一行并将它们添加到列表中。
  • 怎么做?
  • 我试过google your error message,唯一成功的是这个问题。你确定它是正确的?

标签: c# .net json .net-core azure-data-factory-2


【解决方案1】:

JSON 的每一行本身就是一个 JSON 对象。您没有包含所有对象的 JSON 数组。

要阅读它,你只需要重写你的方法来单独反序列化每一行:

private static List<ValueDTO> LoadItems(Stream stream)
{
    var result = new List<ValueDTO>();
    using (var reader = new StreamReader(stream))
    {
        string line = null;
        while ((line = reader.ReadLine()) != null)
        {
            if (!string.IsNullOrEmpty(line))
            {
                result.Add(JsonConvert.DeserializeObject<ValueDTO>(line));
            }
        }
    }
    return result;
}

Try it online

【讨论】:

  • @Sagar 与什么相比?您还有哪些其他选择?
  • 其他选项是,尝试在 azure databricks 中创建有效的 json 格式
  • @Sagar 有什么好处?这样做实际上可能效率较低,因为它会迫使您一次加载所有内容。您可以将上述方法修改为使用yield return,然后在处理它们时只返回行,而不是一次将它们全部加载到内存中。
  • 确定我正在执行您的建议。我会及时向大家发布。希望你在身边
  • 我收到问题中提到的错误:无法将当前 JSON 对象(例如 {"name":"value"})反序列化为 System.Collections.Generic.List ValueDTO' 类型,因为该类型需要要反序列化的 JSON 数组(例如 [1,2,3])。要修复此错误,要么将 JSON 更改为 JSON 数组(例如 [1,2,3]),要么将反序列化类型更改为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像这样的集合类型可以从 JSON 对象反序列化的数组或 List)。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。
【解决方案2】:

以下代码适用于我的机器。我正在使用Newtonsoft.Json 版本12.0.3 定位netcoreapp3.0

using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string json = @"
{'ItemName':'8','Id':1}
{'ItemName':'9','Id':2}
";

            var items = new List<Item>();

            var serializer = new JsonSerializer();

            using (var sr = new StringReader(json))
            {
                using (var jsonTextReader = new JsonTextReader(sr))
                {
                    jsonTextReader.SupportMultipleContent = true;
                    while (jsonTextReader.Read())
                    {
                        var data = serializer.Deserialize<Item>(jsonTextReader);
                        items.Add(data);
                    }

                }
            }

            foreach (Item item in items)
            {
                Console.WriteLine($"{item.Id}: {item.ItemName}");
            }
        }
    }

    public class Item
    {
        public string ItemName { get; set; }
        public int Id { get; set; }
    }
}

【讨论】:

    【解决方案3】:

    请使用Jsonconvert反序列化方法。

     List<object> myDeserializedObjList = (List<object>)Newtonsoft.Json.JsonConvert.DeserializeObject(responseContent, typeof(List<object>));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      相关资源
      最近更新 更多