检查 JSON 中的重复属性
Posted
技术标签:
【中文标题】检查 JSON 中的重复属性【英文标题】:check for duplicate properties in JSON 【发布时间】:2021-08-27 20:14:09 【问题描述】:我们正在开发一个基于 .Net 核心的 Web api 应用程序,为此我们需要针对基于 c# 的类型验证传入的请求主体,该请求主体是 JSON
格式。
我们此时正在评估NJsonSchema
库以查看它是否会引发重复属性错误。
但看起来它不支持此验证。我们还检查了来自 NewtonSoft
的 JSON
架构验证器,但似乎它也不支持重复的属性验证。
下面是我们使用的使用NJsonSchema
的最小化代码-
using NewtonSoft.Json;
public class MyRequest
[JsonRequired]
[JsonProperty("name")]
public string Name get; set;
当我们像这样传递一个 JSON 对象时 -
"name":"abc","name":"xyz"
我们需要我们的 JSON 验证器来为 duplicate property
抛出错误
我们的示例测试如下所示 -
[Test]
public async System.Threading.Tasks.Task SchemaValidation_WithDuplicateProperty_Async()
var jsonString = await File.ReadAllTextAsync("Data//JsonWithDuplicateProperty.json");
var schema = JsonSchema.FromType<MyRequest>();
var errors = schema.Validate(jsonString);
Assert.That(errors.Count(), Is.EqualTo(1));
所以我的问题 - 过去有没有人这样做过?或者是否有任何.net core
的库为重复属性提供JSON
验证和/或可以使用NJsonSchema
或NewtonSoft
来完成。
【问题讨论】:
有趣的是,根据RFC7159,它是合法的。它说:对象中的名称应该是唯一的。 另外值得一提的是,JamesNK 说“Json.NET 中没有办法限制它们。它将使用最后一个值。”,很有趣顺便问一下。 进一步看,似乎使用JsonLoadSettings 可能会有所帮助,并且在这种情况下专门设置DuplicatePropertyNameHandling
seems to throw。
【参考方案1】:
正如@zaggler 所说,使用Newtonsoft,您可以使用DuplicatePropertyNameHandling
枚举。不幸的是,您不能直接在对DeserializeObject
的调用中使用它(在JsonSerializerSettings
中);它必须在 JToken Reader 中使用。有关详细信息,请参阅此讨论主题:
https://github.com/JamesNK/Newtonsoft.Json/issues/931
这是一种以DeserializeObject
-esque 方式包装动作的方法:
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
public class Program
public static void Main()
var json = @"""name"":""abc"",""name"":""xyz""";
var objA = DeserializeObject<MyRequest>(json, new JsonSerializerSettings(), DuplicatePropertyNameHandling.Ignore);
Console.WriteLine(".Ignore: " + objA.Name);
var objB = DeserializeObject<MyRequest>(json, new JsonSerializerSettings(), DuplicatePropertyNameHandling.Replace);
Console.WriteLine(".Replace: " + objB.Name);
var objC = DeserializeObject<MyRequest>(json, new JsonSerializerSettings(), DuplicatePropertyNameHandling.Error);
Console.WriteLine(".Error: " + objC.Name); // throws error before getting here
public static T DeserializeObject<T>(string json, JsonSerializerSettings settings, DuplicatePropertyNameHandling duplicateHandling)
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
using (var stringReader = new StringReader(json))
using (var jsonTextReader = new JsonTextReader(stringReader))
jsonTextReader.DateParseHandling = DateParseHandling.None;
JsonLoadSettings loadSettings = new JsonLoadSettings
DuplicatePropertyNameHandling = duplicateHandling
;
var jtoken = JToken.ReadFrom(jsonTextReader, loadSettings);
return jtoken.ToObject<T>(jsonSerializer);
public class MyRequest
[JsonRequired]
[JsonProperty("name")]
public string Name get; set;
输出:
.忽略:abc
.替换:xyz
运行时异常(第 31 行):属性 当前 JSON 对象中已存在名称“名称”。小路 'name',第 1 行,第 21 位。
见:
https://dotnetfiddle.net/EfpzZu
【讨论】:
以上是关于检查 JSON 中的重复属性的主要内容,如果未能解决你的问题,请参考以下文章