当请求 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,当遇到重复的键时,它会抛出一个代码为 400 的HttpResponseException
,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
{
\...
}
您可以创建一个拦截委托处理程序,该处理程序将在每次收到请求时触发。在其中,您可以获取发送到控制器的数据,并检查它是否有重复的键。创建的处理程序注册如下:
GlobalConfiguration.Configuration.MessageHandlers.Add(new YourDelegateHandler());