【问题标题】:Custom DataTypeAttribute not triggering validation correctly自定义 DataTypeAttribute 未正确触发验证
【发布时间】:2010-10-30 17:27:39
【问题描述】:

与此question相关

我创建了自己的 DateValidationAttibute 以确保字符串采用有效的日期格式(例如,MM/DD/YYYY)

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class DateValidationAttribute : DataTypeAttribute
{
    public DateValidationAttribute() : base(DataType.Date){}

    //MM/DD/YYYY, MM-DD-YYYY
    public override bool IsValid(object value)
    {
        //validation logic
    }
}

我正在尝试使用此代码测试此属性

    [Test]
    public void Test()
    {
        var invalidObject = new TestValidation {DateField = "bah"};
        var validationContext = new ValidationContext(invalidObject, null, null);
        var validationResults = new System.Collections.Generic.List<ValidationResult>();

        bool result = Validator.TryValidateObject(invalidObject, validationContext, validationResults);

        Assert.IsFalse(result);
        Assert.AreEqual(1, validationResults.Count);
    }

    private class TestValidation
    {
        [DateValidation(ErrorMessage = "Invalid Date!")]
        public string DateField { get; set; }
    }

很遗憾,这不起作用。我在 DateValidationAttribute 构造函数和 IsValid 方法处放置了一个断点。它肯定会命中构造函数,但永远不会命中 IsValid 方法。有什么想法吗?

【问题讨论】:

    标签: c# .net asp.net-mvc validation data-annotations


    【解决方案1】:

    方法 TryValidateObject 有一个重载,可以将布尔值 validateAllProperties 作为第四个参数。如果不指定,则默认为false,即只检查部分属性。

    [Test]
    public void Test()
    {
        var invalidObject = new TestValidation {DateField = "bah"};
        var validationContext = new ValidationContext(invalidObject, null, null);
        var validationResults = new System.Collections.Generic.List<ValidationResult>();
    
        //Validate all attributes
        bool result = Validator.TryValidateObject(invalidObject, validationContext, validationResults, true);
    
        Assert.IsFalse(result);
        Assert.AreEqual(1, validationResults.Count);
    }
    

    【讨论】:

      【解决方案2】:

      我从未尝试过使用 DataTypeAttribute 类创建 ValidationAttributes,我不确定这是否有误,但扩展 ValidationAttribute 类一直对我有用。

      “默认情况下,DataTypeAttribute 不进行任何验证。但它确实会影响有关数据呈现方式的模板。”取自this question

      例子:

      [AttributeUsage(AttributeTargets.Field,  AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
      public sealed class MyCustomAttribute : ValidationAttribute
      {
        public MyCustomAttribute()
          : base("Custom Error Message: {0}")
        {
        }
      
        public override bool IsValid(object value)
        {
          return true;
        }
      }
      

      【讨论】:

      • 将我的示例更改为从 ValidationAttribute 扩展无济于事。请记住,DataTypeAttribute 已经从 ValidationAttribute 扩展而来。
      【解决方案3】:

      来自 MSDN link,请注意,只会验证必填字段,不会进行任何其他验证。

      此方法评估每个 ValidationAttribute 实例是 附加到对象类型。它也是 检查是否每个属性 标有RequiredAttribute 是 假如。 不递归 验证属性值 对象

      您需要将测试更改为此,请注意我们在 ValidationContext 上设置 MemberName 并告诉 Validator 验证 invalidObject.DateField 属性。

      [Test]
      public void Test()
      {
           var invalidObject = new TestValidation { DateField = "bah" };
           var validationContext = new ValidationContext(invalidObject,null , null){MemberName = "DateField"};
           var validationResults = new System.Collections.Generic.List<ValidationResult>();
      
           var result = Validator.TryValidateProperty(invalidObject.DateField, validationContext, validationResults);
      
          Assert.IsFalse(result);
          Assert.AreEqual(1, validationResults.Count);
      }
      

      【讨论】:

      • only the required fields will be validated, NOT any other validation您的说法是错误的,引用仅声称验证不是递归执行的。这意味着,如果您有一个具有复杂类型属性的类,该类本身具有标记有验证属性的属性,则这些 inner 属性不会被验证。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-13
      相关资源
      最近更新 更多