C# 可为空的数据类型验证和IValidatableObject.Validate方法

C# 可为空的数据类型验证和IValidatableObject.Validate方法,c#,asp.net-mvc,validation,asp.net-mvc-4,razor,C#,Asp.net Mvc,Validation,Asp.net Mvc 4,Razor,我有一个像下面这样的模型 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<Valida

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

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");
        }
    }
}
公共类MyModel:IValidatableObject
{
[显示名称(“属性名称”)]
[范围(0,9999999,ErrorMessage=“请输入一个介于0和9999999之间的数字”)]
公共int?PropName{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{ 
if(this.PropName==null)
{
返回新的ValidationResult(“未输入属性名称”);
}
}
}
他认为,

  • 当我输入整数值时,我看不到错误消息“Property Name is NOT entered”
  • 当我将该字段留空时,会看到错误消息“未输入属性名称”
  • 当我输入十进制值时,我会看到下面的错误消息
    • 值“xx.xx”对于属性名无效
    • 未输入属性名称
  • 对于案例3,我当然没有想到会看到Validate()方法的消息。i、 e当数据类型出现错误时,Validate()方法不应该被激发

    有人能解释一下为什么会这样吗


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

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

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

  • 为错误的数据类型生成错误
  • 设置为空
  • 为空时生成错误
  • 您是否尝试过使用
    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
    即使在某些字段有错误时也会触发,这是有道理的。