如何在.NETFramework3.5中使用数据注释对C#类进行属性验证?

如何在.NETFramework3.5中使用数据注释对C#类进行属性验证?,c#,validation,.net-3.5,data-annotations,C#,Validation,.net 3.5,Data Annotations,在.NET Framework中有没有一种方法可以将某个方法或验证器交给类被修饰的对象实例,并接收一组错误 我看到有。但是.NET 3.5中有类似的机制吗?通过一些反思,您可以构建自己的验证器,该验证器可以扫描您拥有的属性上的验证属性。这可能不是一个完美的解决方案,但如果您仅限于使用.NET3.5,这似乎是一个轻量级的解决方案,希望您能理解 static void Main(string[] args) { Person p = new Person(); p.Age = 4;

在.NET Framework中有没有一种方法可以将某个方法或验证器交给类被修饰的对象实例,并接收一组错误


我看到有。但是.NET 3.5中有类似的机制吗?

通过一些反思,您可以构建自己的验证器,该验证器可以扫描您拥有的属性上的
验证属性。这可能不是一个完美的解决方案,但如果您仅限于使用.NET3.5,这似乎是一个轻量级的解决方案,希望您能理解

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; }
}
static void Main(字符串[]args)
{
人员p=新人员();
p、 年龄=4岁;
var结果=验证器。验证(p);
results.ToList().ForEach(错误=>Console.WriteLine(错误));
Console.Read();
}       
//简单验证器类
公共静态类验证器
{
//这可能会返回ValidationResult对象等
公共静态IEnumerable验证(对象o)
{
Type Type=o.GetType();
PropertyInfo[]properties=type.GetProperties();
类型属性类型=类型(ValidationAttribute);
foreach(属性中的var propertyInfo)
{
object[]customAttributes=propertyInfo.GetCustomAttributes(attrType,inherit:true);
foreach(customAttributes中的var customAttribute)
{
var validationAttribute=(validationAttribute)customAttribute;
bool isValid=validationAttribute.isValid(propertyInfo.GetValue(o,BindingFlags.GetProperty,null,null));
如果(!isValid)
{
产生返回validationAttribute.ErrorMessage;
}
}
}
}
}
公共阶层人士
{
[必需(ErrorMessage=“名称是必需的!”)]
公共字符串名称{get;set;}
[范围(5,20,ErrorMessage=“必须介于5和20之间!”)
公共整数{get;set;}
}
这会将以下内容打印到控制台:

名称是必需的
必须介于5和20之间


这些数据注释主要在另一个框架中工作,例如MVC w/Razor、Fluent等。如果没有另一个框架,注释只是标记代码,需要一个框架/额外的代码来进行解释

注释本身不是真正的AOP/Intercept,因此注释在使用注释修饰的对象提交给知道如何解释/解析标记代码(通常通过.reflection)的中间框架之前不会执行任何操作

要实现真正的AoP,使注释在本质上起作用,您需要类似PostSharp/Unity等的东西。这些框架在运行/编译时修改IL,并重新路由原始代码。

Linq版本

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);
        }
    }
公共静态类验证程序
{
公共静态IEnumerable验证(对象o)
{
返回类型描述符
.GetProperties(o.GetType())
.Cast()
.SelectMany(pd=>pd.Attributes.OfType()
.Where(va=>!va.IsValid(pd.GetValue(o)))
.选择(xx=>xx.ErrorMessage);
}
}

我不知道.NET 3.5中是否有类似的内容,但如果您愿意使用另一个库,Microsoft的企业应用程序块包含一个验证应用程序块,该应用程序块包含一个验证程序类,该类可以验证用DataAnnotation修饰的对象。是的。这是因为数据注释属性已经实现了。谢谢数据不是来自用户界面;它来自一个我无法控制的外部来源。如果不是这样,我可以简单地使用Winforms或ASP.NET MVC附带的验证。我不认为我需要代码注入式AOP;看见