C# 如何在Web Api Post请求Json中检测重复密钥

C# 如何在Web Api Post请求Json中检测重复密钥,c#,json,asp.net-web-api,json.net,deserialization,C#,Json,Asp.net Web Api,Json.net,Deserialization,当请求Json包含重复键时,我需要从ASP.NET Web API Post请求返回400错误 例如,如果请求是 { "key1": "value1", "key2": 1000, "key2": 2000, "key3": "value3" } 然后我希望抛出错误,因为有两个“key2”键 我的控制器方法看起来像 [HttpPost] public IHttpActionResult PostMethod([FromBody]RequestModel request)

当请求Json包含重复键时,我需要从ASP.NET Web API Post请求返回400错误

例如,如果请求是

{
   "key1": "value1",
   "key2": 1000,
   "key2": 2000,
   "key3": "value3"
}
然后我希望抛出错误,因为有两个“key2”键

我的控制器方法看起来像

[HttpPost]
public IHttpActionResult PostMethod([FromBody]RequestModel request)
{
   .....
}
我的模型是

public class RequestModel
{
    [Required]
    public string Key1 {get; set; }

    [Required]
    public int Key2 {get; set; }

    public string Key3 {get; set; } 
}
在上面的示例中,Json序列化程序似乎乐于接受请求,并用2000或密钥的最后一个实例填充Key2


我想我需要做一些涉及JsonSerializerSettings类的事情,或者实现一个自定义JsonConverter,但是我不确定如何继续。

这里有一个自定义JsonConverter,当遇到Asp.Net Web API应该自动处理的重复密钥时,它会抛出一个带有代码400的
HttpResponseException

class DuplicateJsonConverter : JsonConverter
{
    public override bool CanWrite { get { return false; } }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var paths = new HashSet<string>();
        existingValue = existingValue ?? Activator.CreateInstance(objectType, true);

        var backup = new StringWriter();

        using (var writer = new JsonTextWriter(backup))
            do
            {
                writer.WriteToken(reader.TokenType, reader.Value);

                if (reader.TokenType != JsonToken.PropertyName)
                    continue;

                if (string.IsNullOrEmpty(reader.Path))
                    continue;

                if (paths.Contains(reader.Path))
                       throw new HttpResponseException(HttpStatusCode.BadRequest); //as 400

                paths.Add(reader.Path);
            }
            while (reader.Read());

        JsonConvert.PopulateObject(backup.ToString(), existingValue);
        return existingValue;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

您可以创建一个拦截,它将在每次收到请求时触发。在其中,您可以获取发送到控制器的数据,并检查是否有重复的密钥。 已创建的处理程序的注册方式如下:

GlobalConfiguration.Configuration.MessageHandlers.Add(new YourDelegateHandler());
GlobalConfiguration.Configuration.MessageHandlers.Add(new YourDelegateHandler());