前段时间我不得不创建方法来确定第一个 JSON 对象是否包含在第二个 JSON 对象中。然后我创建了非常简单的方法:
public static partial class JsonOperations
{
[GeneratedRegex(@"\[\d+\]", RegexOptions.Compiled)]
private static partial Regex FindArrayIndexers();
private static IEnumerable<string> GetJsonValuesIdentifiers(IEnumerable<JValue> values)
{
return values.Select(p => $"{FindArrayIndexers().Replace(p.Path, string.Empty)}:{p.Value?.ToString()}");
}
public static bool IsIncludedIn(this JObject first, JObject second)
{
var firstIdentifiers = GetJsonValuesIdentifiers(first.Descendants().OfType<JValue>());
var secondIdentifiers = GetJsonValuesIdentifiers(second.Descendants().OfType<JValue>());
return firstIdentifiers.All(secondIdentifiers.Contains);
}
}
如何运作?我得到 JSON 对象的后代,它们是
JValue
,如此简单的对象,如 int、string 等。后来我得到每个 JSON Path
的 JValue
,并使用 REGEX 从中删除数组索引器。例如:.type.arr[0].xyz
转换为 .type.arr.xyz
,因此这些值的顺序无关紧要。后来我将它与价值结合起来,我得到了标识符,例如.type.arr.xyz:some-string-value
。最后,我只检查第一个 JSON 对象的所有标识符是否都包含在第二个 JSON 对象中。
它似乎工作正常,但我注意到在我的案例中导致严重安全问题的错误。
想象一个像这样的对象:
{
"geolocation":[
{
"lat":-32.364,
"lng":158.207
},
{
"lat":-35.364,
"lng":153.207
}
]
}
第二个:
{
"geolocation":[
{
"lat":-32.364,
"lng":153.207 <-- It's exchanged
},
{
"lat":-35.364,
"lng":158.207 <-- Exchanged with this
}
]
}
我提供的方法会说第一个对象包含在第二个中,但事实并非如此。是的,我已经提到的“标识符”都包括在内,但是“从整体上看”,在这种情况下,我们看到,数组的两个对象表示不同的坐标。
我希望你理解问题,这很难为我解释,但如果你有任何问题请问。