I have a customer class which has both PhoneNumber and Email properties. Using DataAnnotations I can decorate the properties with DataType validation attributes, but I cannot see what that is getting me.
For example:
[DataType(DataType.PhoneNumber)]
public string PhoneNumber {get; set;}
I have a unit test that assigned "1515999A" to this property. When I step through the validation runner the value is considered valid for a phone number. I would have thought this should be invalid.
I google'd around some but couldn't find a decent explanation of what the various enumerated DataTypes actually catch. Is there a worthwhile reference somewhere?
Edit:
Here are the guts of what I'm using for a validation runner...
public virtual XLValidationIssues ValidateAttributes<TEntity>(TEntity entity)
{
var validationIssues = new XLValidationIssues();
// Get list of properties from validationModel
var props = entity.GetType().GetProperties();
// Perform validation on each property
foreach (var prop in props)
ValidateProperty(validationIssues, entity, prop);
// Return the list
return validationIssues;
}
protected virtual void ValidateProperty<TEntity>(XLValidationIssues validationIssues, TEntity entity, PropertyInfo property)
{
// Get list of validator attributes
var validators = property.GetCustomAttributes(typeof(ValidationAttribute), true);
foreach (ValidationAttribute validator in validators)
ValidateValidator(validationIssues, entity, property, validator);
}
protected virtual void ValidateValidator<TEntity>(XLValidationIssues validationIssues, TEntity entity, PropertyInfo property, ValidationAttribute validator)
{
var value = property.GetValue(entity, null);
if (!validator.IsValid(value))
validationIssues.Add(new XLValidationIssue(property.Name, value, validator.FormatErrorMessage(property.Name, value)));
}
I couldn't find much on the web about DataType.PhoneNumber, but I did find this:
http://forums.asp.net/p/1370546/2863383.aspx
In the RTM release, the DataType.EmailAddress is only used to mark the type of data for your own use.
I wanted to find out a bit more, so I pulled out Red Gate's .NET Reflector and started digging around.
Looking at the DataTypeAttribute class, Joseph Daigle is spot on -- each DataType attribute doesn't do any validation; is always returns true (i.e. "valid"). On some data types, some custom display string formatting is done. Phone numbers, however, are pretty much left untouched.
So, I looked into possible solutions to this problem. From what I've found, this looks like the best:
public class EvenNumberAttribute : ValidationAttribute
{
public EvenNumberAttribute() : base(() => Resource1.EvenNumberError) { }
public EvenNumberAttribute(string errorMessage) : base(() => errorMessage) { }
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
if (value == null)
{
return ValidationResult.Success;
}
int convertedValue;
try
{
convertedValue = Convert.ToInt32(value);
}
catch (FormatException)
{
return new ValidationResult(Resource1.ConversionError);
}
if (convertedValue % 2 == 0)
{
return ValidationResult.Success;
}
else
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
}
Of course, that validates whether a number is odd or even. You could write a custom validation attribute for PhoneNumber, Email, etc. that actually does validation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With