Attribute特性封装通用数据验证
2024-10-15
27
在接口接收数据或者数据库写入的时候一般都会进行数据验证。如果在接收到数据或者插入的时候对对象的每个属性进行检验,代码会很臃肿,而且无法复用,通过Attribute特性可以优雅地进行数据验证。
例如我们写一个特性验证属性不能为空,示例代码如下:
特性RequiredAttribute
public class RequiredAttribute:Attribute
{
}
public class User
{
[Required]//非空校验特性标注
public string NickName { get; set; }
public int? Level { get; set; }
}
写一个扩展方法,对对象进行数据验证
//扩展方法
public static bool Validate(this object obj)
{
var type = obj.GetType();
foreach (var prop in type.GetProperties())
{
if (prop.IsDefined(typeof(RequiredAttribute), true))
{
var propValue = prop.GetValue(obj);
if (propValue == null || string.IsNullOrWhiteSpace(propValue.ToString())) {
return false;
}
}
}
return true;
}
//调用扩展方法进行数据验证
User user = new User()
{
NickName = "Paul",
Level = 1
};
//获得校验结果true or false,可以在适当的地方先进行校验再执行后续操作
var result = user.Validate()
像这样就能实现通过Attribute特性封装通用数据验证了,如果别的字段想要做验证,加上这个标签就可以了。原理就是这样,那么要加一些别的复杂的数据验证都可以通过增加Attribute特性来实现。
如果按照上面的写法,每次增加特性后,都要修改扩展方法,我们可以设计一下,让每个特性自己完成检验。定义一个抽象特性,然后每次要增加新的验证就继承它,并且重写它的验证方法。下面我再增加一个验证字符串长度的特性,然后通过更加优雅的方式是实现它,代码如下:
public abstract class AbstracValidateAttribute:Attribute
{
public abstract bool Validate(object obj);
}
//验证非空
public class RequiredAttribute:AbstracValidateAttribute
{
//重写验证方法
public override bool Validate(object obj) {
return (obj == null || string.IsNullOrWhiteSpace(obj.ToString())) ? false : true;
}
}
//验证字符串长度
public class StringLengthAttribute:AbstracValidateAttribute
{
private int _Min { get; set; }
private int _Max { get; set; }
public StringLengthAttribute(int min, int max) {
_Min = min;
_Max = max;
}
public override bool Validate(object obj)
{
if (obj == null || string.IsNullOrWhiteSpace(obj.ToString()))
return false;
var str = obj.ToString();
return (str.Length < _Min || str.Length > _Max) ? false : true;
}
}
public class User
{
[Required]//非空校验特性标注
[StringLength(1,10)]//字符串长度1-10
public string NickName { get; set; }
public int? Level { get; set; }
}
扩展方法修改为:
public static bool Validate(this object obj) {
var type = obj.GetType();
foreach (var prop in type.GetProperties()) {
if (prop.IsDefined(typeof(AbstracValidateAttribute), true)) {
var propValue = prop.GetValue(obj);
var attributeArray = prop.GetCustomAttributes<AbstracValidateAttribute>();
foreach (var item in attributeArray) {
if (!item.Validate(propValue))
return false;
}
}
}
return true;
}
这样一来,以后再要加验证方式的时候,新增一个特性Attribute继承AbstracValidateAttribute,然后重写Validate方法,就可以自定义一个数据验证规则了。无需修改扩展方法,直接给属性加上特性标注即可。
更新于:1个月前赞一波!
相关文章
文章评论
评论问答