2

我们正在开发一个基于 .Net 核心的 web api 应用程序,为此我们需要验证传入的请求主体,该请求主体的JSON格式是基于 c# 的类型。我们此时正在评估NJsonSchema库以查看它是否会引发重复属性错误。但看起来它不支持此验证。我们还检查了JSON模式验证器,NewtonSoft但似乎它也不支持重复的属性验证。

下面是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验证和/或可以使用NJsonSchemaor来完成NewtonSoft

4

1 回答 1

0

正如@zaggler 所指出的,使用 Newtonsoft,您可以使用DuplicatePropertyNameHandling枚举。不幸的是,您不能直接在调用DeserializeObject(in the 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

于 2021-06-10T21:10:13.223 回答