本文作者:小黑黑

在c#中如何使用自定义特性进行数据的检验

小黑黑 7个月前 ( 09-11 ) 1165 抢沙发
在c#中如何使用自定义特性进行数据的检验摘要:       前面我们已经知道了什么是特性以及特性能够做什么,我们在MVC中验证数据时使用 ModelState.IsValid&n...

      前面我们已经知道了什么是特性以及特性能够做什么,我们在MVC中验证数据时使用 ModelState.IsValid 来进行数据的检验,那么我们能不能自己写一套验证规则?答案是可以的,下面我们将使用反射 + 特性来自定义验证规则。

      首先我们来创建一个抽象类 AbstractValidateAttribute,此类作为所有自定义验证特性类的基类,并提供一个抽象方法 Validate() 用于验证数据是否正确。

/// <summary>
/// 抽象类
/// </summary>
public abstract class AbstractValidateAttribute : Attribute
{
    /// <summary>
    /// 抽象验证方法
    /// </summary>
    /// <param name="oValue">需要验证的值</param>
    /// <returns>验证是否通过</returns>
    public abstract bool Validate(object oValue);
}

      接下来我们将创建几个自定义的验证类:RequiredAttribute:非空验证,PhoneAttribute:手机号验证,EmailAttribute:邮箱验证,LengthAttribute:长度验证。

/// <summary>
/// 非空验证
/// </summary>
public class RequiredAttribute : AbstractValidateAttribute
{
    public override bool Validate(object oValue)
    {
        return oValue != null && !string.IsNullOrWhiteSpace(oValue.ToString());
    }
}

/// <summary>
/// 手机号验证
/// </summary>
public class PhoneAttribute : AbstractValidateAttribute
{

    public override bool Validate(object oValue)
    {
        return Regex.IsMatch(oValue.ToString(), "1[3456789]\\d{9}");
    }
}

/// <summary>
/// 邮箱验证
/// </summary>
public class EmailAttribute : AbstractValidateAttribute
{

    public override bool Validate(object oValue)
    {
        return Regex.IsMatch(oValue.ToString(), "(\\w-*\\.*)+@(\\w-?)+(\\.\\w{2,})+");
    }
}

/// <summary>
/// 长度验证
/// </summary>
public class LengthAttribute : AbstractValidateAttribute
{
    private int Max = 0;
    private int Min = 0;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="max">最大长度</param>
    /// <param name="min">最小长度</param>
    public LengthAttribute(int max, int min)
    {
        this.Max = max;
        this.Min = min;
    }


    public override bool Validate(object oValue)
    {
        int length = oValue.ToString().Length;
        return length >= Min && length <= Max;
    }
}

      然后我们创建一个 ValidateExtension的扩展类,里面提供一个泛型扩展方法 Validate(),并在此方法中使用反射获取待验证的属性值,并对其进行验证。

/// <summary>
/// 验证扩展类
/// </summary>
public static class ValidateExtension
{
    /// <summary>
    /// 验证属性值是否正确
    /// </summary>
    public static bool Validate<T>(this T t)
    {
        Type type = t.GetType();

        //获取类型中所有属性
        foreach (PropertyInfo property in type.GetProperties())
        {
            //该属性是否有继承至AbstractValidateAttribute的特性
            if (property.IsDefined(typeof(AbstractValidateAttribute), true))
            {
                //获取属性的值
                object oValue = property.GetValue(t);

                //一个属性上面可能会有多个特性,所以找到所有的继承至AbstractValidateAttribute的特性
                foreach (AbstractValidateAttribute attribute in property.GetCustomAttributes(typeof(AbstractValidateAttribute), true))
                {
                    //验证数据是否正确
                    if (!attribute.Validate(oValue))
                    {
                        return false;
                    }
                }
            }
        }

        return true;
    }
}

      接下我们创建一个测试项目,并在测试项目中添加一个People类,并为里面的属性添加相关的特性,最后编写一个测试方法,我们将使用测试方法来测试数据是否正确。

public class People
{
    /// <summary>
    /// 姓名
    /// </summary>
    [Length(5, 2)]
    [Required]
    public string Name { get; set; }

    [Phone]
    [Required]
    public string Phone { get; set; }

    [Email]
    public string Email { get; set; }
}

[TestClass]
public class ValidateTest
{
    [TestMethod]
    public void Test_LengthAttribute()
    {
        People people = new People
        {
            Name = "张三",
            Phone = "18888888888",
            Email = "test@test.com"
        };

        bool result = people.Validate();
        Assert.IsTrue(result);
    }
}

image.png

我们可以修改相关属性值来依次验证我们的自定义规则是否正确。

分享到: 网站分享代码

发表评论

快捷回复:

评论列表 (暂无评论,1165人围观)参与讨论

还没有评论,来说两句吧...