自定义DataTypeAttribute不能正确触发验证

时间:2010-10-30 17:27:40

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

与此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方法。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

TryValidateObject方法有一个重载,它可以将boolean 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);
}

答案 1 :(得分:0)

我从未尝试使用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;
  }
}

答案 2 :(得分:0)

从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);
}