【问题标题】:Why getting exception message as null为什么将异常消息设为空
【发布时间】:2017-03-10 08:50:11
【问题描述】:

我有基于ASP.Net WebAPI 的应用程序。下面是我的 DTO。

 public class CustomerTO
{

    [Required(ErrorMessage="Name required")]
    [StringLength(50, MinimumLength = 3, ErrorMessage = "Name invalid")]
    public string Name { get; set; }

    [Required(ErrorMessage="CountryId required")]
    [Range(1,250,ErrorMessage="CountryId invalid")]
    public int Country { get; set; }
}

我的 API 控制器。

 [HttpPost]
    [AllowAnonymous]
    public HttpResponseMessage Post([FromBody]CustomerTO model)
    {
        if (ModelState.IsValid)
        {
           //my stuff
        }
        else
        {
              var msg =  ModelState.SelectMany(s => s.Value.Errors).FirstOrDefault().ErrorMessage;

            }
        }

如果用户将任何必填字段作为Null 传递,它将返回Data Annotations 中提到的正确错误消息,而如果我将string 传递给CountryId,它将进入else 条件(@987654329 @) 但是 ErrorMessage 是空的。

如果我调试并快速查看以下语句。

 msg = ModelState.SelectMany(s => s.Value.Errors).FirstOrDefault().Exception.Message;

它返回 - Could not convert string to integer: en. Path 'Country', line 6, position 14.

为什么在这种情况下,我没有收到 CountryId Invalid 的错误消息

我如何得到这个?

【问题讨论】:

  • 我会认为是因为您输入的字符串 Country 正试图绑定到整数 Country。如果你在“ModelState.Isvalid”上放一个断点并检查“model”的内容......你能在模型中看到同样的异常吗?
  • @Wheels73,是的,也这样做了
  • 我相信范围验证器不适合字符串输入,即它们只有在它是有效整数时才会触发。它不强制传入的类型。尝试将您的注释更改为正则表达式。 [RegularExpression("([1-9][0-9]*)")]
  • @Wheels73,有道理。我会检查谢谢:)
  • 如果可行,我将作为答案发布! :)

标签: c# validation asp.net-web-api data-annotations modelstate


【解决方案1】:

使用RegularExpressionAttribute 不会阻止RangeAttribute 引发“无法将字符串转换为整数”异常。所以只过滤正确的:

var msg = ModelState.SelectMany(s => s.Value.Errors)
                    .FirstOrDefault(_ => _.Exception == null)
                    .ErrorMessage;

【讨论】:

  • 是的。它在没有脏补丁的情况下满足了我的要求谢谢:)
【解决方案2】:

据我所知,这是一个常见问题:SO question 1SO question 2

根据代码,任何验证属性都有creating a wrapper,派生自RequestFieldValidatorBase。每个包装器调用ValidationAttributeIsValid 方法。在RequestFieldValidatorBase 的方法Validate 中传递表单值进行验证。

所以,RequiredAttribute 不会失败,因为表单值不为空且不是null,而RangeAttribute 不会失败,因为它在将此值转换为 int 时遇到问题。

为了实现您想要的行为,建议您创建自己的验证属性或使用RegularExpressionAttribute。你可以看看this answer

【讨论】:

    【解决方案3】:

    我相信范围验证器不适合字符串输入,即它们仅在它是有效整数时才会触发。它不强制传入的类型。 尝试将您的注释更改为正则表达式。

    [RegularExpression("([1-9][0-9]*)", ErrorMessage = "Country code invalid")]
    public string Country { get; set; }
    

    参考此链接Integer validation against non-required attributes in MVC

    作为脏补丁,我将我的属性从 int 修改为 string 并用正则表达式装饰它。

    【讨论】:

    • @Kgn-web,如果你保持数据类型为int那么只需修改错误信息过滤:var msg = ModelState.SelectMany(s => s.Value.Errors).FirstOrDefault(_ => _.Exception == null).ErrorMessage;
    • @AndriyTolstoy,是的。正确,那太好了。请将其发布为 ans 并附上简短说明
    猜你喜欢
    • 2012-01-26
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 2018-09-05
    • 2012-03-12
    相关资源
    最近更新 更多