【问题标题】:System Text Json read single object from array of objects系统文本 Json 从对象数组中读取单个对象
【发布时间】:2022-01-15 09:21:45
【问题描述】:

我正在尝试使用新的系统文本 Json 库从我的 json 数组中读取单个对象。 我的 json 看起来像这样:

[
  {
    "Id": "test1",
    "Version": "16.0.461",
  },
  {
    "Id": "test2",
    "Version": "2.1.0",
  }
]

这只是一个例子。一个 Json 对象实际上有大约 12 个属性。但是假设c#中有一个类,看起来像这样:

     public class Data
     {
            public string Id { set; get; }
            public string Version { set; get; }
     }

我只想获取 id 与给定名称匹配的包,我尝试这样:

    private static ObjectData GetSingleData(string jsonString, string objectName)
    {
                var options = new JsonDocumentOptions
                {
                    AllowTrailingCommas = true
                };

                using (JsonDocument document = JsonDocument.Parse(jsonString, options))
                {
                    ArrayEnumerator arrayEnumerator = document.RootElement.EnumerateArray();
                    //ObjectEnumerator objectEnumerator1 = document.RootElement.EnumerateObject();
                    while (arrayEnumerator.MoveNext())
                    {
                        JsonElement current = arrayEnumerator.Current;
                        if (objectName.Equals(current.GetProperty("id"))) 
                        {
                            //here the conversion from current to object should happen, but I don't know how                      
                        }
                    }
                }

                return null;
     }

是否有可能将 JsonElement 转换为我的 Data 类的实例?

【问题讨论】:

  • 您是否尝试过反序列化而不是尝试逐个访问元素?例如JsonSerializer.Deserialize<Item[]>(json,options);
  • 这确实有效,但我认为我可以反序列化直到找到正确的元素而不是反序列化我的整个 jsonstring。
  • JsonDocument.Parse 也会解析整个文档。
  • 有没有办法绕过这个?
  • 您可以使用 Utf8JsonReader 逐个读取元素,但这适用于ReadOnlySpan<byte>byte[] 形式的UTF8 序列。您必须使用 varbytes=Encoding.UTF8.GetBytes(json);,或直接从 UTF8 JSON 文件中读取。你一开始想做什么? System.Text.Json 还不是通用的 JSON 解析器,它适用于 Web 应用程序序列化,其中有效负载 UTF8 并且必须在被使用之前完全解析/反序列化。跨度>

标签: json .net-core-3.0


【解决方案1】:

使用这样的东西:

JsonElement current = document.RootElement;  
if (objectName.Equals(current.GetProperty("Id"))) 
{
     //But i'm using TryGetProperty
     //This is example code for first element in JSON array
     string id = current[0].GetProperty("Id").GetString(); //test1
     string version = current[0].GetProperty("Version").GetString(); //16.0.461
     
     //And now you can create your Data object
     Data data_object = new Data(id, version)
}

如果我理解正确,这应该可以。

UPD: 我不建议你使用标准库,所以改用 Json.NET,这个库非常方便,工作速度更快(例如,我实现了 ~0.2 秒的反序列化速度link for more info

UPD 2:
对于 .NET 5:

【讨论】:

    【解决方案2】:

    .NET 6JsonElement.Deserialize<T>()(source)

    var obj = current.Deserialize<ObjectData>();
    

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 2014-07-22
      • 2018-01-24
      • 1970-01-01
      • 1970-01-01
      • 2012-04-19
      • 2014-08-10
      • 1970-01-01
      相关资源
      最近更新 更多