2016-03-04 72 views
4

我有一个要求,当请求Json包含重复键时,从ASP.NET Web API Post请求返回400错误。如何检测Web API中的重复键发布请求Json

例如,如果请求是

{ 
    "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年接受请求并填充键2,或任何密钥的最后一个实例是。

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

回答

1

这里是一个自定义JsonConverter它抛出一个HttpResponseException与代码400,当遇到一个复制的钥匙,其Asp.Net的Web API会自动处理它。

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

并且您应该使用此转换器修饰您的RequestModel类。

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

您可以创建一个拦截DelegateHandler,每当您收到请求时它都会触发。在这里你可以获得发送到控制器的数据并检查它是否有重复的键。 创建处理程序是这样注册的:

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