为什么获取异常消息为空
Why getting exception message as null
我有基于 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
传递,它会 returns Data Annotations
中提到的正确错误消息,而如果我将 string
传递给 CountryId
,进入else
条件(*ModelState.IsValid = false*
)
但是 ErrorMessage 是空的。
虽然如果我调试并将以下语句放在快速观察中。
msg = ModelState.SelectMany(s => s.Value.Errors).FirstOrDefault().Exception.Message;
它returns - Could not convert string to integer: en. Path 'Country', line 6, position 14.
为什么在这种情况下,我没有收到 CountryId Invalid
的错误消息
我如何得到这个?
据我所知,这是一个常见问题:SO question 1, SO question 2。
根据代码,任何验证属性都有 creating a wrapper, derived from RequestFieldValidatorBase
。每个包装器调用 ValidationAttribute
的 IsValid
方法。在 RequestFieldValidatorBase
的方法 Validate
中传递表单值进行验证。
因此,RequiredAttribute
不会失败,因为表单值不为空且不是null
,而RangeAttribute
不会失败,因为它在将此值转换为int时遇到问题.
为了实现您想要的行为,建议创建您自己的验证属性或使用 RegularExpressionAttribute
。你可以看看this answer.
我认为范围验证器不适合字符串输入,即它们仅在输入有效整数时触发。它不强制执行传入的类型。
尝试将注释更改为正则表达式。
[RegularExpression("([1-9][0-9]*)", ErrorMessage = "Country code invalid")]
public string Country { get; set; }
参照此linkInteger validation against non-required attributes in MVC
作为脏补丁,我将我的 属性 从 int
修改为 string
并用正则表达式对其进行了修饰。
使用 RegularExpressionAttribute does not prevent RangeAttribute 抛出 "Could not convert string to integer" 异常。所以只筛选正确的:
var msg = ModelState.SelectMany(s => s.Value.Errors)
.FirstOrDefault(_ => _.Exception == null)
.ErrorMessage;
我有基于 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
传递,它会 returns Data Annotations
中提到的正确错误消息,而如果我将 string
传递给 CountryId
,进入else
条件(*ModelState.IsValid = false*
)
但是 ErrorMessage 是空的。
虽然如果我调试并将以下语句放在快速观察中。
msg = ModelState.SelectMany(s => s.Value.Errors).FirstOrDefault().Exception.Message;
它returns - Could not convert string to integer: en. Path 'Country', line 6, position 14.
为什么在这种情况下,我没有收到 CountryId Invalid
我如何得到这个?
据我所知,这是一个常见问题:SO question 1, SO question 2。
根据代码,任何验证属性都有 creating a wrapper, derived from RequestFieldValidatorBase
。每个包装器调用 ValidationAttribute
的 IsValid
方法。在 RequestFieldValidatorBase
的方法 Validate
中传递表单值进行验证。
因此,RequiredAttribute
不会失败,因为表单值不为空且不是null
,而RangeAttribute
不会失败,因为它在将此值转换为int时遇到问题.
为了实现您想要的行为,建议创建您自己的验证属性或使用 RegularExpressionAttribute
。你可以看看this answer.
我认为范围验证器不适合字符串输入,即它们仅在输入有效整数时触发。它不强制执行传入的类型。 尝试将注释更改为正则表达式。
[RegularExpression("([1-9][0-9]*)", ErrorMessage = "Country code invalid")]
public string Country { get; set; }
参照此linkInteger validation against non-required attributes in MVC
作为脏补丁,我将我的 属性 从 int
修改为 string
并用正则表达式对其进行了修饰。
使用 RegularExpressionAttribute does not prevent RangeAttribute 抛出 "Could not convert string to integer" 异常。所以只筛选正确的:
var msg = ModelState.SelectMany(s => s.Value.Errors)
.FirstOrDefault(_ => _.Exception == null)
.ErrorMessage;