【问题标题】:ModelStateDictionairy Malformed json web apiModelStateDictionairy 格式错误的 json web api
【发布时间】:2017-04-10 13:49:49
【问题描述】:

我正在使用 modelstate 属性来检查我的模型是否有效。 这一切都很好,但是当我向我的 json 正文添加更多属性(我的模型中不存在)时,它说模型仍然有效。

如何检查发送的 json 正文以匹配 C# 模型?

这是我现在的模型:

public class User
    {
        public int Id { get; set; }
        public string IdentityServerId { get; set; }
        [Required(ErrorMessage = "Email is required")]
        [EmailAddress(ErrorMessage = "Not a valid emailaddress")]
        public string Email { get; set; }
        [Required(ErrorMessage = "Name is required")]
        public string Name { get; set; }
        public bool IsActive { get; set; }
    }

正确格式的 json 是:

{
    "Name": "Klaas",
    "Email": "eifjelfij@sdf"
}

这给出了一个 200 OK 来创建相应的用户。

但是当我发送这个 json 时:

{
    "Name": "Arjan",
    "Email": "eifjelfij@sdf",
    "eifj":"eflijelfij"
}

它仍然会创建用户,但我想给用户一个错误消息而不是用户创建。

【问题讨论】:

  • 较低的也是有效的 json,因为你没有属性 eifj 所以它会被有效地丢弃。模型验证只能验证模型中存在...的属性;)

标签: c# .net json asp.net-core .net-core


【解决方案1】:

您可以在应用程序启动期间更改 JSON.NET 设置以将不存在的属性作为错误处理...

services.AddMvc()
    .AddJsonOptions(options =>
    {
        options.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Error;
    });

这应该会导致您在控制器操作中的User 参数将是null,从而导致验证失败。

在你的 Action 中你也可以特别处理它。

public async Task<IActionResult> Post([FromBody]Models.User user)
{
    if(!ModelState.IsValid) 
    {
        if(user==null)
        {
            // user is null, which means we couldn't deserialize it or 
            // no data was sent with the request
            return BadRequest(new { Error = "Invalid formatted data." });
        }

        // return errors, since we know user is not null
        return BadRequest(ModelState);
    }
}

【讨论】:

  • 这正是我所需要的!这简化了很多哈哈
【解决方案2】:

将 JSON 转换为您的用户对象,然后使用反射检查您的任何用户对象属性是否为空。试试这个:

User user = CreateUserFromJson(json); // assuming user object already created by you
if (TypeDescriptor.GetProperties(user).Cast<PropertyDescriptor>().Any(prop => prop.GetValue(user) == null))
{
// json is missing fields
}

【讨论】:

  • 嗯没有默认方法吗?这表明我首先必须反序列化我的 json 响应(这是 mvc imho 的责任),然后检查道具是否与我的模型中的匹配。没关系,这确实是我现在正在做的事情,但我想也许aspnetnewtonsoft json 已经为此做了一些事情。目前在控制器内我正在检索这样的数据:public async Task&lt;IActionResult&gt; Post([FromBody] Models.User user) {//do stuff}
  • 我不熟悉。您可能可以创建自己的扩展 Newtonsoft 的 JSON 反序列化器,然后在调用父函数实际反序列化 json 之前在其中实现此 json 字符串检查
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多