views:

42

answers:

3

I am new about attributes. I just try it on my console application.

So how can i validate my person instance below example ?

class Person
    {
        [StringLength(8,ErrorMessage="Please less then 8 character")]
        public string Name { get; set; }

    }
+3  A: 

The only function that Attribute can handle is describe, provide some descriptive data with member. They are purely passive and can't contain any logic. (There are some AOP frameworks that can make attributes active). So if you want logic you have to create another class that will read attributes using MemberInfo.GetCustomAttributes and do the validation and return results.

Andrey
A: 

Below code shows how to determine validation for only properties and give idea validation for methods ,classes etc.

public class DataValidator
    {
        public class ErrorInfo
        {
            public ErrorInfo(string property, string message)
            {
                this.Property = property;
                this.Message = message;
            }

            public string Message;
            public string Property;
        }

        public static IEnumerable<ErrorInfo> Validate(object instance)
        {
            return from prop in instance.GetType().GetProperties()
                   from attribute in prop.GetCustomAttributes(typeof(ValidationAttribute), true).OfType<ValidationAttribute>()
                   where !attribute.IsValid(prop.GetValue(instance, null))
                   select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty));
        }
    }

After adding this code to project we can use it like:

    var errors =DataValidator.Validate(person);

    foreach (var item in errors)
    {
        Console.WriteLine(item.Property +" " + item.Message);
    }
Freshblood
+1  A: 

Here is simple code example without reflection.

class Program
{
    static void Main(string[] args)
    { 
        var invalidPerson = new Person { Name = "Very long name" };
        var validPerson = new Person { Name = "1" };

        var validator = new Validator<Person>();

        Console.WriteLine(validator.Validate(validPerson).Count);
        Console.WriteLine(validator.Validate(invalidPerson).Count);

        Console.ReadLine();
    }
}

public class Person
{
    [StringLength(8, ErrorMessage = "Please less then 8 character")]
    public string Name { get; set; }
}

public class Validator<T> 
{
    public IList<ValidationResult> Validate(T entity)
    {
        var validationResults = new List<ValidationResult>();
        var validationContext = new ValidationContext(entity, null, null);
        Validator.TryValidateObject(entity, validationContext, validationResults, true);
        return validationResults;
    }
}
Yury Tarabanko
I haven't checked your code enough but i think your solution is better because you have used native DataAnnonations classes. I also was trying that but hadn't enough experience for figure out.
Freshblood
I have used this approach in a couple of small projects. The only problem with it arise in case you want to use MetadataType attribute since you have to perform manual registration of AssociatedMetadataTypeTypeDescriptionProvider.
Yury Tarabanko
Works perfect and this is what i was looking for . It even doesn't check only properties.
Freshblood
Ahh it checks all validate attributes but it doesn't work for fields why ?
Freshblood
As far as I know System.ComponentModel.DataAnnotations.Validator works only with properties. If you need to validate fields either you could implement your own validator (as you already did for properties) or pay attention on more sophisticated validation framework (Validation Application Block in Enterprise Application Library for example).
Yury Tarabanko