繁体   English   中英

使用自定义属性进行非负验证使用反射

[英]Using custom attribute for non negative validation using reflection

我是c#的新手,并试图掌握自定义属性的使用以及如何使用它来使用反射进行数据验证。 例如,如果您必须查看收集的年份数据是否有四位数而且它是非负数。 我们如何使用自定义属性和反射来实现这样的逻辑。

欣赏是否提供了示例代码

您可以执行类似Data Annotation Validators的操作 大局是这样的:

  1. 您可以使用某些字段定义对象(字段使用属性进行修饰)
  2. 使用验证程序验证具有用这些属性修饰的字段的对象。

模型类可能是这样的

class Person
{
    [StringNotNullOrEmpty]
    string FirstName { get; set; }

    [Range(Min = 0, Max = 100)]
    int Age {get; set; }
}

验证器有点像这样:

class Validator
{
    public IEnumerable<FieldValidationResult> ValidateObject(object ob)
    {
        List<FieldValidationResult> list = new List<FieldValidationResult>();

        var properties = ob.GetType().GetProperties();

        foreach(var property in properties)
        {
            var res = ValidateField(ob, property);

            list.Add(res);
        }

        return list;
    }

    private FieldValidationResult ValidateField(object ob, PropertyInfo prop)
    {
        var attributes = prop.GetCustomAttributes();

        foreach(var att in attributes)
        {
            if (att is StringNotNullOrEmptyAttribute)
            {
                string strVal = prop.GetValue(ob) as string;

                if (string.IsNullOrEmpty(strVal))
                    return new FieldValidationResult("Field {0} can not be empty")

                return null;
            }

            if (att is RangeAttribute)
            {
                // validate range attribute
                   var rangeAtt = (RangeAttribute)att;
                   int intVal = (int)prop.GetValue(ob);

                    if (rangeAtt.Min > intVal || rangeAtt.Max < intVal)
                              return new FieldValitaionResult("Field {0} must be between {1} and {2}, prop.Name, rangeAtt.Min, rangeAtt.Max);

                           return null;
            }
        }
    }
}

并像这样使用它:

Person p = new Person();
p.FirstName = "";
p.Age = 10;

Validator validator = new Validator();

var validationResults = validator.ValidateObject(p);

您可以声明这样的自定义属性......

public class MyAttribute : Attribute
{
    public MyAttribute(bool b)
    {
        MustBePositive = b;
    }
    public bool MustBePositive { get; set; }
}

该属性有一个布尔值,表示该值是否必须为正。

然后你可以像这样装饰成员......

    [MyAttribute(true)]
    public int MyInt { get; set; }

一个完整的验证方法是......

public class Data
{
    [MyAttribute(true)]
    public int MyInt { get; set; }
    public void Validate()
    {
        foreach (PropertyInfo pi in typeof (Data).GetProperties())
        {
            var atts = pi.GetCustomAttributes(typeof (MyAttribute), false).FirstOrDefault();
            if (atts != null)
            {
                var myAtt = atts as MyAttribute;
                if (myAtt != null)
                {
                    if (myAtt.MustBePositive)
                    {
                        var propValue = (int)pi.GetValue(this);
                        if (propValue < 0)
                        {
                            Console.WriteLine(@"Invalid");
                        }
                    }
                }
            }
        }
    }
}

当MyInt属性为负时,此方法将打印“无效”。 Validate方法本身在实例中查询使用MyAttribute修饰的属性。 它获取实例值并对其进行测试。

可以在Validate方法上实现优化,例如在初始化时执行所有查找,但上面的代码给出了一个完整的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM