开发者

Custom DataTypeAttribute not triggering validation correctly

Related to this question

I have created my own DateValidationAttibute to make sure a string is in a valid date format (e.g., 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
    }
}

I am trying to test this attribute with this code

    [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; }
    }

Unfortunately this isn't working. I put a breakpoint at the DateValidationAttribute constructor, and the IsValid method. It definitely hits the constructor, but never hits the IsValid method. Any i开发者_高级运维deas?


The method TryValidateObject has an overload that can take a boolean validateAllProperties as a fourth parameter. If not specified, it defaults to false, which is when it only checks some attributes.

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


I've never tried creating ValidationAttributes using the DataTypeAttribute class and I'm not sure if this is wrong but extending the ValidationAttribute class has always worked for me.

"DataTypeAttribute doesn't do any validation by default. But it does influence templates regarding how the data is presented." taken from this question

Example :

[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;
  }
}


From MSDN link, note that only the required fields will be validated, NOT any other validation.

This method evaluates each ValidationAttribute instance that is attached to the object type. It also checks whether each property that is marked with RequiredAttribute is provided. It does not recursively validate the property values of the object.

You will want to change your test to this, note that we are setting the MemberName on the ValidationContext and telling the Validator to validate the invalidObject.DateField property.

[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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜