c# - 控制台环境中的 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
以某种方式从它自身的属性中调用该方法吗?
我会对此进行一些解释,在此先感谢您!
解决方案
属性本身只是属性的“装饰器”。如果没有调用它,它将不会被自动执行或使用。
但是,在您的情况下,当您可以使用属性本身时,我看不到使用属性的意义:
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;
}
}
您的代码实际上只允许一个null
or""
值,我猜这与您想要的相反。此版本仅在字符串不为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
_ 通过这种方式,代码变得更加面向未来,因为您可以针对接口进行编程并随时添加新的验证属性。IValidationAttribute
NotNullAttribute
推荐阅读
- javascript - 使用 Material-UI 的 Gatsby:为什么要创建 PageContext?
- mysql - MySQL 集成测试“未找到查询”
- docker - 在多个ec2节点上设置zookeeper集群时0.0.0.0是什么意思
- django - 一起使用 Django SimpleHistory 和 TabularInline
- javascript - 如何在锚标签点击下载图像文件而不在新标签中打开图像?
- c - 读取特定格式的字符串
- r - 格式化 y 轴数字
- distributed-computing - PAXOS 算法共识之谜
- bash - 将getopts选项自动解析为bash中同名的动态变量
- python - Jupyter Notebook 内核一直很忙