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);
}
精彩评论