我试图通过使用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
语句的行上出错:
没有财产或字段'姓名'存在于'对象'
中
如果我改为使用匿名对象,用这个替换第二行,它就可以正常工作:
var person = new { Name = "Jane Doe", Occupation = "FBI Consultant"};
是否有另一种反序列化json字符串的方法,它允许我通过字符串谓词查询它以检查json对象是否匹配?
编辑:json-string和Where-statement是动态的,由用户提供。有很多属性,在执行代码之前我不知道它们的名字。字段的名称和值都由用户提供。
答案 0 :(得分: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");
答案 1 :(得分:0)
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);
答案 2 :(得分:0)
修改强>
感谢您的评论,这实际上有所作为。 对不起有点迟到的回答,但也许它仍然会有所帮助。
以下完整测试适用于动态参数名称和参数值:
// 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);
答案 3 :(得分:0)
在阅读了答案以及其他帖子后,我创建了这个解决方案:
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;
}
希望它对某人有帮助。