Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a good reference for data annotations in regards to how DataType works?

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)));
    }
like image 322
Sailing Judo Avatar asked Aug 31 '09 13:08

Sailing Judo


1 Answers

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.

like image 73
Doug Avatar answered Sep 23 '22 20:09

Doug