为什么复杂的对象验证会像这样工作,而简单的参数却不会?
Why does complex object validation work like this, where as simple parameters do not?
在 ASP.NET 核心应用程序的控制器中,它已经用 [ApiController]
属性装饰,如果我们为需要以下对象的端点传递一个空的 JSON 对象(来自请求正文,默认情况下):
public class ComplexObject
{
[Range(1, int.MaxValue, ErrorMessage = "Prop1 must contain a positive number.")]
public int Prop1 { get; set; }
[Range(1, int.MaxValue, ErrorMessage = "Prop2 must contain a positive number.")]
public int Prop2 { get; set; }
}
验证失败,这是应该的(属性是 int 类型,它们被分配了该类型的默认值,即 0,验证检查失败。
但是,如果我们有一个端点不接受复杂对象(来自正文),而是来自 URI 的 2 个 int 变量,如果用户只是点击没有查询字符串(URI 参数)的端点,验证似乎通过了,即使在调试时两个属性都被分配了值 0。
在这种情况下使验证通过而不是不通过有什么不同?以下是我如何修饰 URI 参数的属性:
public IActionResult SomeAction([Range(1, int.MaxValue, ErrorMessage = "Prop1 must contain a positive number.")] int prop1,
[Range(1, int.MaxValue, ErrorMessage = "Prop2 must contain a positive number.")] int prop2)
{
...
}
显然,如果我还添加 [Required]
属性,一切都会按预期进行。但是为什么 SomeObject 不需要 [Required]
属性就可以工作呢? [Range]
基本上是一箭双雕!
public IActionResult SomeAction([Required][Range(1, int.MaxValue, ErrorMessage = "Prop1 must contain a positive number.")] int prop1,
[Required][Range(1, int.MaxValue, ErrorMessage = "Prop2 must contain a positive number.")] int prop2)
{
...
}
操作参数是可选的,只有在它们存在时才会被验证。因此,如果您没有通过其中一项,则不会应用 Range
验证。当您 post 整个对象时,您就满足了第一个条件:参数具有值。因此,将对该对象进行验证,然后对它包含的所有属性进行验证。
那么,由于您的属性是不可为 null 的整数,如果您不传递值,它们将默认为零。零超出了可接受的范围,因此验证失败。它实际上并没有在这里应用必需的验证。您只是在利用默认值不被下一个验证接受的事实。
在 ASP.NET 核心应用程序的控制器中,它已经用 [ApiController]
属性装饰,如果我们为需要以下对象的端点传递一个空的 JSON 对象(来自请求正文,默认情况下):
public class ComplexObject
{
[Range(1, int.MaxValue, ErrorMessage = "Prop1 must contain a positive number.")]
public int Prop1 { get; set; }
[Range(1, int.MaxValue, ErrorMessage = "Prop2 must contain a positive number.")]
public int Prop2 { get; set; }
}
验证失败,这是应该的(属性是 int 类型,它们被分配了该类型的默认值,即 0,验证检查失败。
但是,如果我们有一个端点不接受复杂对象(来自正文),而是来自 URI 的 2 个 int 变量,如果用户只是点击没有查询字符串(URI 参数)的端点,验证似乎通过了,即使在调试时两个属性都被分配了值 0。
在这种情况下使验证通过而不是不通过有什么不同?以下是我如何修饰 URI 参数的属性:
public IActionResult SomeAction([Range(1, int.MaxValue, ErrorMessage = "Prop1 must contain a positive number.")] int prop1,
[Range(1, int.MaxValue, ErrorMessage = "Prop2 must contain a positive number.")] int prop2)
{
...
}
显然,如果我还添加 [Required]
属性,一切都会按预期进行。但是为什么 SomeObject 不需要 [Required]
属性就可以工作呢? [Range]
基本上是一箭双雕!
public IActionResult SomeAction([Required][Range(1, int.MaxValue, ErrorMessage = "Prop1 must contain a positive number.")] int prop1,
[Required][Range(1, int.MaxValue, ErrorMessage = "Prop2 must contain a positive number.")] int prop2)
{
...
}
操作参数是可选的,只有在它们存在时才会被验证。因此,如果您没有通过其中一项,则不会应用 Range
验证。当您 post 整个对象时,您就满足了第一个条件:参数具有值。因此,将对该对象进行验证,然后对它包含的所有属性进行验证。
那么,由于您的属性是不可为 null 的整数,如果您不传递值,它们将默认为零。零超出了可接受的范围,因此验证失败。它实际上并没有在这里应用必需的验证。您只是在利用默认值不被下一个验证接受的事实。