简体   繁体   English

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

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

I am new to c# and trying to grasp the use of custom attributes and how to use it for data validation using reflection. 我是c#的新手,并试图掌握自定义属性的使用以及如何使用它来使用反射进行数据验证。 For example, if you have to see if collected year data has four digits and it is non negative number. 例如,如果您必须查看收集的年份数据是否有四位数而且它是非负数。 How can we use custom attribute and reflection to implement such logic. 我们如何使用自定义属性和反射来实现这样的逻辑。

Appreciate if sample code is provided 欣赏是否提供了示例代码

You can do something similar like Data Annotation Validators . 您可以执行类似Data Annotation Validators的操作 The big picture is like this: 大局是这样的:

  1. You define an object with some fields (the fields are decorated with attributes) 您可以使用某些字段定义对象(字段使用属性进行修饰)
  2. Use validator that validates an object that has fields decorated with those attributes. 使用验证程序验证具有用这些属性修饰的字段的对象。

The model class could be like this 模型类可能是这样的

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

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

The validator is kinda like this: 验证器有点像这样:

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;
            }
        }
    }
}

And use it like this: 并像这样使用它:

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

Validator validator = new Validator();

var validationResults = validator.ValidateObject(p);

You can declare a custom attribute like this... 您可以声明这样的自定义属性......

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

This attribute has a boolean indicating whether the value must be positive. 该属性有一个布尔值,表示该值是否必须为正。

You can then decorate members with it like this... 然后你可以像这样装饰成员......

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

A complete validation method for this would be... 一个完整的验证方法是......

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");
                        }
                    }
                }
            }
        }
    }
}

This method will print "Invalid" when the MyInt property is negative. 当MyInt属性为负时,此方法将打印“无效”。 The Validate method itself queries the instance for properties decorated with MyAttribute. Validate方法本身在实例中查询使用MyAttribute修饰的属性。 It gets the instance value and tests it. 它获取实例值并对其进行测试。

There are optimizations that can be implemented on the Validate method such as doing all the lookups at initialization time, but the above code gives a fully working example. 可以在Validate方法上实现优化,例如在初始化时执行所有查找,但上面的代码给出了一个完整的示例。

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

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