How does one do property validation of a C# class using Data Annotations in .NET Framework 3.5?

扶醉桌前 提交于 2019-12-08 16:01:22

问题


Is there a way in the .NET Framework to hand some method or validator an object instance whose class is decorated with Data Annotations, and receive a collection of errors?

I see that there is a way to do this in .NET 4.x. But is there a similar mechanism in .NET 3.5?


回答1:


With a bit of reflection, you could build your own validator which scans the ValidationAttributes on the properties you have. It may not be a perfect solution, but if you're limited to using .NET 3.5, this seems like a lightweight solution, hopefully you get the picture.

static void Main(string[] args)
{

    Person p = new Person();
    p.Age = 4;

    var results = Validator.Validate(p);

    results.ToList().ForEach(error => Console.WriteLine(error));

    Console.Read();
}       

// Simple Validator class
public static class Validator
{
    // This could return a ValidationResult object etc
    public static IEnumerable<string> Validate(object o)
    {
        Type type = o.GetType();
        PropertyInfo[] properties = type.GetProperties();
        Type attrType = typeof (ValidationAttribute);

        foreach (var propertyInfo in properties)
        {
            object[] customAttributes = propertyInfo.GetCustomAttributes(attrType, inherit: true);

            foreach (var customAttribute in customAttributes)
            {
                var validationAttribute = (ValidationAttribute)customAttribute;

                bool isValid = validationAttribute.IsValid(propertyInfo.GetValue(o, BindingFlags.GetProperty, null, null, null));

                if (!isValid)
                {
                    yield return validationAttribute.ErrorMessage;
                }
            }
        }
    }
}

public class Person
{
    [Required(ErrorMessage = "Name is required!")]
    public string Name { get; set; }

    [Range(5, 20, ErrorMessage = "Must be between 5 and 20!")]
    public int Age { get; set; }
}

This prints out the following to the Console:

Name is required!
Must be between 5 and 20!




回答2:


Linq Version

public static class Validator
{
    public static IEnumerable<string> Validate(object o)
        {
            return TypeDescriptor
                .GetProperties(o.GetType())
                .Cast<PropertyDescriptor>()
                .SelectMany(pd => pd.Attributes.OfType<ValidationAttribute>()
                                    .Where(va => !va.IsValid(pd.GetValue(o))))
                                    .Select(xx => xx.ErrorMessage);
        }
    }



回答3:


Those data annotation stuff mainly works in context of another framework eg. MVC w/ Razor, Fluent etc. Without another framework the annotations are just that, they're marker code, and will require a framework/extra code to do the interpretation.

Annotation by itself is not true AOP/Intercept, and hence the annotations do nothing until the object decorated with annotation is submitted to an intermediary framework that knows how to interpret / parse the marker codes (usually via. reflection).

For true AoP that could make the annotations work intrinsically you will need something like PostSharp/Unity etc. These frameworks modify the IL at run/compile time and reroutes the original code.



来源:https://stackoverflow.com/questions/17285988/how-does-one-do-property-validation-of-a-c-sharp-class-using-data-annotations-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!