使用JSON.NET将递归JSON反序列化为C#
我们正在使用为应用程序的用户创建动态筛选组件: 最有趣的功能之一是能够序列化过滤器集,如下所示:使用JSON.NET将递归JSON反序列化为C#,c#,json,recursion,json.net,deserialization,C#,Json,Recursion,Json.net,Deserialization,我们正在使用为应用程序的用户创建动态筛选组件: 最有趣的功能之一是能够序列化过滤器集,如下所示: { "condition": "AND", "rules": [ { "id": "filterGroup1", "field": "filterGroup1", "type": "string", "input": "select", "operator": "contains", "value": "1" }, { "id": "filt
{
"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; }
}
公共类QueryBuilderFilter
{
公共字符串条件{get;set;}
公共IEnumerable规则{get;set;}
}
公共阶级规则
{
公共字符串Id{get;set;}
公共字符串字段{get;set;}
公共字符串类型{get;set;}
公共字符串输入{get;set;}
公共字符串运算符{get;set;}
公共字符串值{get;set;}
公共IEnumerable筛选器{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 );
JsonSerializerSettings jsonSettings=新的JsonSerializerSettings
{
TypeNameHandling=TypeNameHandling.All,
TypeNameAssemblyFormat=FormatterAssemblyStyle.Full,
错误=(发送方,事件参数)=>
{
eventArgs.ErrorContext.Handled=true;
}
};
QueryBuilderFilter反序列化=JsonConvert.DeserializeObject(过滤,jsonSettings);
直到IEnumerable属性完美运行,这意味着除此属性之外的所有数据都是水合的。但是,第三个节点返回null:
此节点应对应于子项,但我无法找到正确或干净的方法来执行此操作。不使用类型和手动解析可能是一种选择,但这听起来像是一个非常密集和昂贵的解决方案,而我相信应该有更简单的解决方案。如果我预先知道项目的数量,这不会是一个真正的问题,但是控件允许无限的查询构建,所以我需要能够动态地处理这个问题
有什么建议吗?根据你的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; }
}
公共类规则
{
公共字符串Id{get;set;}
公共字符串字段{get;set;}
公共字符串类型{get;set;}
公共字符串输入{get;set;}
公共字符串运算符{get;set;}
公共字符串值{get;set;}
公共字符串条件{get;set;}
公共IEnumerable规则{get;set;}
}
这是用C#翻译的JSON模型:
var过滤器=新规则
{
条件=“和”,
规则=新列表{
新规则
{
Id=“filterGroup1”,
Field=“filterGroup1”,
Type=“string”,
输入=“选择”,
Operator=“contains”,
Value=“1”
},
新规则
{
Id=“filterGroup2”,
Field=“filterGroup2”,
Type=“string”,
输入=“选择”,
Operator=“contains”,
Value=“3”
},
新规则
{
条件=“或”,
规则=新列表{
新规则
{
Id=“filterGroup1”,
Field=“filterGroup1”,
Type=“string”,
输入=“选择”,
Operator=“contains”,
Value=“1”
}
}
}
}
}
规则
需要条件和规则,然后@puropoix这是正确的。纪尧姆也有同样的解决方案,因为他在早些时候,所以我给了他荣誉。起初我对这个解决方案有点怀疑,但如果你考虑一下,它实际上是有意义的。谢谢。最初的问题是,在规则数组中存储了两种不同的结构。它对JSON模型有效,但对强类型C#结构无效。
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"
}
}
}
}
}