using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataValidateAttribute
{
/// <summary>
/// 所有验证类特性的父类,所有的用于验证的特性都将继承此类
/// </summary>
/*
AttributeTargets.Parameter 标识该特性作用于 方法的参数
Inherited = true 标识该特性可以被继承
AllowMultiple = true 标识可以多次标注
*/
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = true)]
public abstract class ValidateAttribute
: Attribute
{
public ValidateAttribute()
{
}
public ValidateAttribute(string msg)
{
this.Message = msg;
}
/// <summary>
/// 被验证的参数名称
/// </summary>
private string _argumentName;
/// <summary>
/// 抛出错误的信息
/// </summary>
private string _message;
/// <summary>
/// 获取被验证的参数名称
/// </summary>
public string ArgumentName
{
set
{
_argumentName = value;
}
protected get
{
return _argumentName;
}
}
/// <summary>
/// 异常的提示信息
/// </summary>
public string Message
{
protected get
{
return _message;
}
set
{
_message = value;
}
}
/// <summary>
/// 验证该值是否符合指定的规则
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public abstract void IsValidation(object value);
}
}
Step 2: 实现我们的验证用的子类
[NotNullAttribute]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataValidateAttribute
{
public class NotNullAttribute : ValidateAttribute
{
public NotNullAttribute()
{
}
public NotNullAttribute(string msg) : base(msg)
{
}
public override void IsValidation(object value)
{
if (value == null)
{
throw new ArgumentNullException(this.ArgumentName + " " + Message);
}
}
}
}
[ValidationAgeAttribute]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataValidateAttribute
{
public class ValidationAgeAttribute : ValidateAttribute
{
public ValidationAgeAttribute()
{
}
public ValidationAgeAttribute(string msg) : base(msg)
{
}
public override void IsValidation(object value)
{
int age = Convert.ToInt32(value);
if (age <= 0)
{
throw new ArgumentException(this.ArgumentName + " " + this.Message);
}
}
}
}
Step 3 抽取一个统一使用的用于验证的方法:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DataValidateAttribute
{
public static class ValidateContext
{
/// <summary>
/// 验证方法的参数是否合法
/// </summary>
/// <param name="values">被判断的值,值得顺序必须按照参数特性的顺序来传值</param>
public static void Validate(object[] values)
{
//从方法栈中拿到刚执行的方法
MethodInfo method = (MethodInfo)(new StackTrace().GetFrame(1).GetMethod());
//获取到方法的参数
ParameterInfo[] parameterInfos = method.GetParameters();
if (parameterInfos.Length == 0)
return;
int index = 0;
//遍历所有的参数
foreach (var item in parameterInfos)
{
//获取被标记的特性的数组
ValidateAttribute[] attributes = (ValidateAttribute[])Attribute.GetCustomAttributes(item, typeof(ValidateAttribute));
if (attributes != null)
{
foreach (var attr in attributes)
{
//如果没有异常就证明验证通过
try
{
attr.ArgumentName = item.Name;
attr.IsValidation(values[index]);
}
//如果有异常那么就表示验证没有通过,抛出我们指定的异常
catch (Exception e)
{
throw e;
}
}
index += 1;
}
}
}
}
}
Step 5 检验效果:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataValidateAttribute
{
class Program
{
static void Main(string[] args)
{
Console.ReadKey();
}
/// <summary>
/// 普通方式来验证参数的方法
/// </summary>
/// <param name="name"></param>
/// <param name="gender"></param>
/// <param name="age"></param>
static void Dome1(string name, string gender, int age)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
if (gender == null)
{
throw new ArgumentNullException("gender");
}
if (age <= 0)
{
throw new ArgumentException("age");
}
}
/// <summary>
/// 使用特性来验证参数的方法
/// </summary>
/// <param name="name"></param>
/// <param name="gender"></param>
/// <param name="age"></param>
static void Demo2([NotNull("名字你还想空?")]string name, [NotNull]string gender, [ValidationAge("年龄错误 不能小于0")]int age)
{
ValidateContext.Validate(new object[] { name, gender, age });
}
}
}