如何使用 System.Linq.Dynamic 检查 JSON 对象是不是与谓词匹配
Posted
技术标签:
【中文标题】如何使用 System.Linq.Dynamic 检查 JSON 对象是不是与谓词匹配【英文标题】:How can I use System.Linq.Dynamic to check if a JSON object matches a predicate如何使用 System.Linq.Dynamic 检查 JSON 对象是否与谓词匹配 【发布时间】:2017-06-28 22:50:36 【问题描述】:我正在尝试使用 Json.NET 和 System.Linq.Dynamic 将复杂的 json 对象与用户定义的过滤器/谓词进行匹配。这是我的代码:
var json = @"""Name"":""Jane Doe"",""Occupation"":""FBI Consultant""";
dynamic person = JObject.Parse(json);
var people = new[] person ;
var isMatch = people.Where("Name=@0", "Jane Doe").Any();
Console.WriteLine(isMatch);
这给了我一个与Where
-statement 相关的错误:
“对象”类型中不存在属性或字段“名称”
如果我改用匿名对象,通过用这个替换第二行,它可以正常工作:
var person = new Name = "Jane Doe", Occupation = "FBI Consultant";
是否有另一种反序列化 json 字符串的方法,可以让我通过字符串谓词查询它以检查 json 对象是否匹配?
EDIT:json-string 和 Where-statement 是动态的,由用户提供。有很多属性,在执行代码之前我不知道它们的名称。字段名称和值均由用户提供。
【问题讨论】:
这可能会有所帮助:***.com/questions/18734996/…SelectToken
使用通配符*
运算符可能会满足您的需求。见Searching for a specific JToken by name in a JObject hierarchy。
【参考方案1】:
将您的 Where
语句替换为:
var isMatch = people.Where(x => x.Name == "Jane Doe").Any();
可以简化为:
var isMatch = people.Any(x => x.Name == "Jane Doe");
这可能不是您想要的,但简单的 System.Linq 可以轻松满足您的需求。
对于您想要动态执行此操作的情况:
var isMatch = people.Any(x => x.GetValue("Name") == "Jane Doe");
【讨论】:
我的需要是通过字符串谓词查询json字符串中的对象,所以你是对的,这对我没有帮助。 @Espo 我真的理解你,但如果你仍然想考虑只使用 Json,你可以再次查看我的答案。【参考方案2】:var json = @"""Name"":""Jane Doe"",""Occupation"":""FBI Consultant""";
dynamic person = JObject.Parse(json);
var people = new List<object>() person ;
var filedName = "Name";
var searchValue = "Jane Doe";
var any = people.Any(p => p.GetType().GetProperty(filedName).GetValue(p, null) as string == searchValue);
【讨论】:
字段的名称和值都由用户提供,所以这对我没有帮助,抱歉。 你知道你可以在那里使用变量吗?【参考方案3】:在阅读了答案和其他帖子后,我创建了这个解决方案:
void Main()
var json = @"""Name"":""Jane Doe"",""Occupation"":""FBI Consultant"", ""Info"": ""Age"":28, ""Gender"":""Female""";
Console.WriteLine("Match Name: " + json.JsonMatch("Name", "Jane Doe"));
Console.WriteLine("Match Age: " + json.JsonMatch("Info.Age", "28"));
public static bool JsonMatch(this string json, string key, string value)
dynamic obj = JObject.Parse(json);
var values = obj.PropertyValues();
foreach (var element in values)
if (element.Path == key)
return element.Value == value;
if (element.Path == null)
foreach (var subelement in element)
if (subelement.Path == key)
return subelement.Value == value;
return false;
希望它对某人有所帮助。
【讨论】:
【参考方案4】:编辑
感谢您的 cmets,这实际上有所作为。 抱歉回答晚了一点,但也许它仍然会有所帮助。
以下使用动态参数名称和参数值的完整测试:
// Given
var json = @"""Name"":""Jane Doe"",""Occupation"":""FBI Consultant""";
var person = JObject.Parse(json);
var people = new[] person;
// When
var isMatch = people.Any(p => p.GetValue("Name").Value<string>() == "Jane Doe");
// Then
Assert.IsTrue(isMatch);
【讨论】:
我需要使用字符串谓词/过滤器。字段的名称和值都是由用户提供的,所以这对我没有帮助,抱歉。以上是关于如何使用 System.Linq.Dynamic 检查 JSON 对象是不是与谓词匹配的主要内容,如果未能解决你的问题,请参考以下文章
System.Linq.Dynamic.Core - 查询嵌套对象
使用Dynamic LINQ创建高级查询服务 #yyds干货盘点#