【问题标题】:Why does complex object validation work like this, where as simple parameters do not?为什么复杂的对象验证会这样工作,而简单的参数却不行?
【发布时间】:2020-01-10 12:09:01
【问题描述】:

在已使用[ApiController] 属性修饰的 ASP.NET Core 应用程序的控制器中,如果我们为需要以下对象的 Endpoint 传递一个空 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】:

    动作参数是可选的,只有在它们存在时才会被验证。因此,如果您没有通过其中之一,则不会应用 Range 验证。当您发布整个对象时,您已经满足了第一个条件:参数有一个值。因此,将对该对象进行验证,然后对其包含的所有属性进行验证。

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

    【讨论】:

    • 是否有可能不以某种方式将对象传递给需要对象的端点?我试过了,但似乎对象本身永远不能为空 - 只有一个空的(只是花括号。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多