C# 将动态 JSON JToken 解析为列表

Posted

技术标签:

【中文标题】C# 将动态 JSON JToken 解析为列表【英文标题】:C# Parse a dynamic JSON JToken to a List 【发布时间】:2021-12-23 03:06:31 【问题描述】:

我们能否将动态 JSON 解析为对象列表 List<DiffModel>

public class DiffModel 

  public string Property  get; set; 
  public string OldValue  get; set; 
  public string NewValue  get; set; 
 

JSON 是在 library 的帮助下生成的,它有助于比较 2 个 JSON 对象并找出差异。差异被存储为JToken

借助以下工具生成的示例 JSON JToken 值 JToken patch = jdp.Diff(left, right)方法


  "Id": [
    78485,
    0
  ],
  "ContactId": [
    767304,
    0
  ],
  "TextValue": [
    "text value",
    "text14"
  ],
  "PostCode": [
    null
  ]

从 JSON 中,对象中第一项的值为

DiffModel [0] =  Property ="id" OldValue="78485" NewValue="0"
DiffModel [1] =  Property ="contactId" OldValue="767304" NewValue="0"
DiffModel [2] =  Property ="TextValue" OldValue="text value" NewValue="text14"
DiffModel [3] =  Property ="PostCode" OldValue= null NewValue=null

我们能否在动态 JSON 的属性之间导航并构建类似的模型

【问题讨论】:

对于您的特定情况,您可以使用patch.AsJEnumerable().OfType<JProperty>().Select(p=>new DiffModel ... )。但是,返回的 JToken 并不像您的示例那么简单。你可以阅读full specs。 【参考方案1】:

您可以像这样定义数据模型:

struct DiffModel

    public string Property  get; init; 
    public object OldModel  get; init; 
    public object NewModel  get; init; 

我使用过struct,但你可以使用classrecord 任何你喜欢的方式。

然后您可以将JToken 转换为Dictionary<string, object[]>

关键是属性名称 该值将是属性值
var rawModel = patch.ToObject<Dictionary<string, object[]>>();

最后,您只需要DiffModelKeyValuePair&lt;string, object[]&gt; 之间的映射:

var diffModels = rawModel
    .Select(pair => new DiffModel
    
        Property = pair.Key,
        OldModel = pair.Value.First(),
        NewModel = pair.Value.Last(),
    ).ToArray();

【讨论】:

错误:Newtonsoft.Json.JsonSerializationException:错误转换值“到类型'System.Collections.Generic.Dictionary2[System.String,System.Object[]]'. Path ''. ---&gt; System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.Dictionary2[System.String,System.Object[]]。这是错误我得到了 @Sebastion 我已使用您的 json 作为我的转换输入 (JToken patch = JObject.Parse(json))。你说的那个问题我没遇到过。但是让我仔细检查一下。 @Sebastian 我无法重现您的异常。您能否在您的问题中分享您的 leftright 变量,以便能够在我的本地计算机上生成差异? 补丁的值如下 "Id": [ 78487, 0 ], "ContactId": [ 767304, 0 ], "TextValue": [ "scs re gregre", "asdas" ] 我的错误 在我的代码块中缺少将字符串解析为 JSON 的初始步骤。看起来这在正常用例中有效。我必须进一步调试以查看它如何处理空值 [在新值或旧值部分]

以上是关于C# 将动态 JSON JToken 解析为列表的主要内容,如果未能解决你的问题,请参考以下文章

C# Newtonsoft.Json解析json字符串处理 - JToken 用法

如何将 JSON 字符串转换为 C# IEnumerable<JToken>

将 JSON 解析为 JToken 时如何将所有键更改为小写

如何在 C# 中动态转换来自 Json.NET 的解析 JSON 结果?

如何解析JSON.NET中的匿名数组?

如何使用 Newtonsoft.Json 将包含数组数组的 json 对象解析为 C# 中的对象列表?