【问题标题】:Nullable Data type validation and IValidatableObject.Validate methodNullable 数据类型验证和 IValidatableObject.Validate 方法
【发布时间】:2014-05-20 15:16:54
【问题描述】:

我有一个像下面这样的模型

public class MyModel : IValidatableObject
{
    [DisplayName("Property Name")]
    [Range(0, 9999999, ErrorMessage = "Please enter a number between 0 and 9999999")]
    public int? PropName { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    { 
        if (this.PropName == null)
        {
            yield return new ValidationResult("Property Name is NOT entered");
        }
    }
}

在视图中,

  1. 当我输入整数值时,我没有看到错误消息“未输入属性名称”
  2. 当我将该字段留空时,我看到错误消息“未输入属性名称”
  3. 当我输入十进制值时,我看到下面的错误消息
    • 值“xx.xx”对于属性名称无效。
    • 未输入属性名称

对于案例 3,我当然没想到会看到来自 Validate() 方法的消息。即 Validate() 方法不应该在数据类型出现错误时触发。

谁能解释一下为什么会这样?

视图只是使用@Html.ValidationSummary() 来显示消息。

【问题讨论】:

    标签: c# asp.net-mvc validation asp.net-mvc-4 razor


    【解决方案1】:

    我找不到关于字段验证、字段绑定到值以及Validate 在模型绑定时执行的顺序的文档。但是,我认为这些字段在 Validate 执行之前被绑定到它们的值。因此PropNameValidate 中为空。

    这意味着PropName 输入为十进制时的事件顺序是:

    1. 为错误的数据类型生成错误
    2. 设置为空
    3. 为 null 生成错误

    您是否尝试过使用RequiredAttribute 而不是您的自定义验证?这意味着你不需要实现IValidatableObject,你的代码就变成了

    public class MyModel
    {
        [Required]
        [DisplayName("Property Name")]
        [Range(0, 9999999, ErrorMessage = "Please enter a number between 0 and 9999999")]
        public int? PropName { get; set; }
    }
    

    【讨论】:

    • 感谢您的回复。我不能真正使用[Required] 属性,因为我拥有的实际验证比我上面说明的要复杂得多。以上只是解释流程的示例。到目前为止,我相信IValidatableObject.Validate() 永远不会在出现数据注释错误时触发,并且我假设数据类型错误也遵循相同的逻辑。但显然并非如此。
    • Validate 是类级别的验证方法。数据注释执行字段级验证。如果一个字段验证失败,那么其他字段仍会全部检查并返回所有错误。因此,即使某些字段出现错误,Validate 也总是会触发。
    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多