一段时间以前,我必须创建一个方法,来确定第一个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等。稍后,我获取每个JValue
的JSON Path
,并使用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
}
]
}
我提供的方法会说第一个对象包含在第二个对象中,但这不是真的。是的,我已经提到的“标识符”都包括在内,但是“整体来看”,在这种情况下,我们看到,数组的两个对象表示不同的坐标。
此外,一般假设比较的JSON总是具有相同的结构。如果不是,则第一不能包括在第二中。
我希望你能理解这个问题,这很难为我解释,但如果你有任何问题请问。
1条答案
按热度按时间zlhcx6iw1#
成功的关键是通过分组为JSON标识符提供更多的上下文。这是完整的工作代码:
我已经测试了问题中提供的JSON,并由以下人员生成:https://json-generator.com
请注意问题中包含的假设。这段代码只在JSON结构相同的情况下工作(根据假设)。如果他们不是,它就不会工作。