如何在Web Api Post请求Json中检测重复键

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

例如,如果请求是

{ "key1": "value1", "key2": 1000, "key2": 2000, "key3": "value3" } 

然后我想要抛出错误,因为有两个“key2”键。

我的控制器方法看起来像

 [HttpPost] public IHttpActionResult PostMethod([FromBody]RequestModel request) { ..... } 

和我的RequestModel模型一样

 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(); 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(); } } 

你应该使用这个转换器装饰你的RequestModel类。

 [JsonConverter(typeof(DuplicateJsonConverter))] class RequestModel { \\... } 

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

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