如何使用System.Linq.Dynamic检查JSON对象是否与谓词匹配

时间:2017-02-10 14:36:25

标签: c# linq json.net linq-to-objects dynamic-linq

我试图通过使用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是动态的,由用户提供。有很多属性,在执行代码之前我不知道它们的名字。字段的名称和值都由用户提供。

4 个答案:

答案 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;
}

希望它对某人有帮助。