【问题标题】:Deserializing recursive JSON to C# with JSON.NET使用 JSON.NET 将递归 JSON 反序列化为 C#
【发布时间】:2016-04-03 13:18:00
【问题描述】:

我们正在使用jQuery Querybuilder plugin 为我们应用程序的用户创建一个动态过滤组件:

最有趣的功能之一是过滤器集的序列化能力,如下所示:

{
 "condition": "AND",
  "rules": [
  {
   "id": "filterGroup1",
   "field": "filterGroup1",
   "type": "string",
   "input": "select",
   "operator": "contains",
   "value": "1"
 },
 {
   "id": "filterGroup2",
   "field": "filterGroup2",
   "type": "string",
   "input": "select",
   "operator": "contains",
   "value": "3"
 },
 {
   "condition": "OR",
   "rules": [
     {
      "id": "filterGroup1",
      "field": "filterGroup1",
      "type": "string",
      "input": "select",
      "operator": "contains",
      "value": "1"
    }
  ]
}
]
}

您可能注意到,数据是递归的:第三个节点与根节点具有相同的类型。在将其反序列化到服务器时,这给了我一些问题。目前我有这个:

public class QueryBuilderFilter
{       
    public string Condition { get; set; }
    public IEnumerable<Rule> Rules { get; set; }
}

 public class Rule
{
    public string Id { get; set; }
    public string Field { get; set; }
    public string Type { get; set; }
    public string Input { get; set; }
    public string Operator { get; set; }
    public string Value { get; set; }

    public IEnumerable<QueryBuilderFilter> Filters { get; set; }
}

这就是我所说的:

 JsonSerializerSettings jsonSettings = new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.All,
            TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
            Error = (sender, eventArgs) =>
            {
                eventArgs.ErrorContext.Handled = true;
            }
        };

QueryBuilderFilter deserialized = JsonConvert.DeserializeObject<QueryBuilderFilter>(filtering, jsonSettings );

在 IEnumerable 属性完美之前的一切,这意味着除此属性之外的所有数据都已水合。但是,第三个节点返回 null:

该节点应该对应于子项,但我无法找到正确或干净的方法来执行此操作。不使用类型并手动解析可能是一种选择,但这听起来像是一个非常密集且昂贵的解决方案,而我相信应该有更简单的解决方案。如果我预先知道项目的数量,这不会是一个真正的问题,但是控件允许无限的查询构建,所以我需要能够动态地处理它。

有什么建议吗?

【问题讨论】:

  • Rule 需要条件和规则,然后you get this
  • @Plutonix 是正确的。纪尧姆也有同样的解决方案,因为他更早,所以我把功劳归功于他。

标签: c# json recursion json.net deserialization


【解决方案1】:

根据你的 JSON,你可以试试这个模型吗:

public class Rule
{
  public string Id { get; set; }
  public string Field { get; set; }
  public string Type { get; set; }
  public string Input { get; set; }
  public string Operator { get; set; }
  public string Value { get; set; }
  public string Condition { get; set; }
  public IEnumerable<Rule> Rules { get; set; }
}

这是你用 C# 翻译的 JSON 模型:

var filter = new Rule
{
    Condition = "AND",
    Rules = new List<Rule> {
        new Rule 
        {
            Id = "filterGroup1",
            Field = "filterGroup1",
            Type = "string",
            Input = "select",
            Operator = "contains",
            Value = "1"
        },
        new Rule 
        {
            Id = "filterGroup2",
            Field = "filterGroup2",
            Type = "string",
            Input = "select",
            Operator = "contains",
            Value = "3"
        },
        new Rule
        {
            Condition = "OR",
            Rules = new List<Rule> {
                new Rule 
                {
                    Id = "filterGroup1",
                    Field = "filterGroup1",
                    Type = "string",
                    Input = "select",
                    Operator = "contains",
                    Value = "1"
                }
            }
        }
    }
}

【讨论】:

  • 一开始我对这个解决方案有点怀疑,但如果你仔细想想,它实际上是有道理的。
  • 谢谢。最初的问题是您在规则数组中存储了 2 个不同的结构。它适用于 JSON 模型,但不适用于强类型 C# 结构。
猜你喜欢
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多