c# - 如何检测 Web Api Post 请求 Json 中的重复键

标签 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”键而抛出错误。

我的 Controller 方法看起来像

[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 或 key 的最后一个实例填充 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();
    }
}

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

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

关于c# - 如何检测 Web Api Post 请求 Json 中的重复键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35794869/

相关文章:

android - Android 中的 Json DateTime 解析

javascript - 解析 JSON 对象以获取唯一记录

asp.net-web-api - ASP.NET Web API 帮助页面上的空模型属性描述

c# - 对象的 readOnlyCollection 中带有 linq 的 Where 子句

c# - 为什么空字符串不是连接的标识?

c# - WinForms.ReportViewer - 呈现的页面数

c# - 无参数匿名方法可以分配给有参数委托(delegate)

java - Android 编码将 Json 值填充到 Spinner 获取所选 TextView 或编辑的所有值

jquery - Web API OWIN 从 $.AJAX POST withCredentials :true 接收空数据

asp.net-web-api - asp.net webapi odata $metadata 中缺少反向属性