首页 > 解决方案 > 控制台环境中的 C# 自定义属性验证

问题描述

我的问题是关于在 C# 中使用自定义属性进行验证。

我不太明白验证是如何工作的。我已经声明了一个包含验证规则的属性,但是当错误应该被抛出时,它不是。

属性:

[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
    public bool IsValid(object value)
    {
        if (value is string && (string)value != "")
        {
            return false;
        }
        return true;
    }

}

在属性内部,我检查属性是否为字符串类型,以及它的值是否为空字符串,因为这是我必须检查的。

任务是检查一个属性是否是 astring并且如果它是一个空字符串那么它是无效的,否则它是。

我的Person班级:

class Person
{
    [NotNull]
    public string Name { get; set; }
}

在这里,我正在应用自定义属性。

主要方法:

class Program
{
    static void Main(string[] args)
    {
        Person p1 = new Person();
        p1.Name = "";

        Console.WriteLine("Validation done");
        Console.ReadKey();
    }
}

这是我实例化Person类并为属性分配一个空字符串的地方Name。我猜这就是应该抛出错误的地方。

所以我的问题是为什么不应用验证?我应该IsValid以某种方式从它自身的属性中调用该方法吗?

我会对此进行一些解释,在此先感谢您!

标签: c#validationattributes

解决方案


属性本身只是属性的“装饰器”。如果没有调用它,它将不会被自动执行或使用。

但是,在您的情况下,当您可以使用属性本身时,我看不到使用属性的意义:

private string _name = "";

public string Name
{
   get
   {
      return _name;
   }
   set
   {
      if ( string.IsNullOrEmpty(value) )
      {
          //throw or fallback
      }
      else
      {
          _name = value;
      }
   }
}

进行基本值验证正是属性设置器非常适合的工作。如果有人使用了无效值,您可以抛出异常,或者设置一个备用值。

如果您仍然更喜欢使用属性,您仍然需要一些代码来执行验证本身。而且,除非执行验证,否则任何人都可以为该属性分配任何有效值。

例如,ASP.NET MVC在模型绑定期间使用属性验证 - 它检查绑定模型类上的验证属性,并在操作方法开始执行之前对其进行验证。

属性验证示例

这是一个简单的示例,说明如何使您的代码与反射一起工作。

首先是验证属性的略微更新版本:

[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
    public bool IsValid(object value)
    {
        if (!string.IsNullOrEmpty(value as string))
        {
            return false;
        }
        return true;
    }
}

您的代码实际上只允许一个nullor""值,我猜这与您想要的相反。此版本仅在字符串不为null空且不为空时有效。

现在在你的类中创建一个Validate方法:Program

private static bool Validate(object model)
{
    foreach (var propertyInfo in model.GetType().GetProperties())
    {                
        foreach (var attribute in propertyInfo.GetCustomAttributes(true))
        {
            var notNullAttribute = attribute as NotNullAttribute;
            if (notNullAttribute != null)
            {
                if (!notNullAttribute.IsValid(propertyInfo.GetValue(model)))
                {
                    return false;
                }
            }
        }
    }
    return true;
}

这基本上收集了传入参数类型的所有属性,检查属性的所有属性,NotNullAttribute然后IsValid针对model.

最后,您可以从以下位置调用它Main

static void Main(string[] args)
{
    Person p1 = new Person();
    p1.Name = "d";

    if (Validate(p1))
    {
        Console.WriteLine("Valid");
    }
    else
    {
        Console.WriteLine("Invalid");
    }

    Console.WriteLine("Validation done");
    Console.ReadKey();
}

现在,如果您打算添加更多验证属性,我将首先创建一个接口:

public interface IValidationAttribute
{
    bool IsValid(object value);
}

IValidationAttribute然后从代替. Validate_ 通过这种方式,代码变得更加面向未来,因为您可以针对接口进行编程并随时添加新的验证属性。IValidationAttributeNotNullAttribute


推荐阅读