【问题标题】:C# Parse a dynamic JSON JToken to a ListC# 将动态 JSON JToken 解析为列表
【发布时间】: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

标签: c# json json.net


【解决方案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 的初始步骤。看起来这在正常用例中有效。我必须进一步调试以查看它如何处理空值 [在新值或旧值部分]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 2020-08-13
  • 1970-01-01
  • 2017-04-13
  • 1970-01-01
  • 2020-05-30
相关资源
最近更新 更多