为什么复杂的对象验证像这样,而简单的参数却不这样?

问题描述 投票:1回答:1

在ASP.NET Core应用程序的控制器中,该控制器已经用[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)
{
   ...
}
c# validation asp.net-core model-view-controller data-annotations
1个回答
2
投票
动作参数是可选的,只有存在时才进行验证。因此,如果您没有通过其中之一,则不会应用Range验证。发布整个对象时,您已经满足了第一个条件:参数具有值。因此,验证将在该对象以及随后包含的所有属性上进行。

然后,由于您的属性是不可为null的整数,如果您不传递值,则它们将默认为零。零超出可接受范围,因此验证失败。它实际上并没有在此处应用所需的验证。您只是利用了以下事实:默认值是下一个验证不可接受的事实。

© www.soinside.com 2019 - 2024. All rights reserved.