1. 程式人生 > >Asp.net MVC 模型驗證如何做到模型欄位與action 動作的解耦

Asp.net MVC 模型驗證如何做到模型欄位與action 動作的解耦

1場景 某一天我在教我學生搭建Asp.net 框架做專案的時候 發現做一個登入 後臺模型驗證需要用到驗證“使用者名稱”和“密碼”不能為空。 然後我建立了一個模型 帶有這兩個欄位非空的特性

後面我學生問我老師如果我要修改使用者資訊的時候不需要驗證使用者名稱和密碼為空 這剛才的模型好像不能用 後臺還是會驗證使用者名稱和密碼不能為空

後來我給他解釋的是 最好一個action 接受資料的模型 用一個model 也就是說登入 用一個模型 修改密碼 用一個模型 新增和修改使用者資訊用一個模型
如此本質上對我們使用者資訊表的操作根據UI的業務操作要新增好幾個模型
後面我查找了很多資料 也沒找到合適的第三方模型驗證框架 可以給模型欄位新增特性的驗證 但是可以根據action 動作來使部分特性生效。於是我自己把模型驗證的特性類做了重新。程式碼如下 希望對大家有所幫助。

程式碼如下

Code:1

namespace MVC_GaoJi
{
public class MyValidateHelper
{
///
/// 當前請求Action 是否包含指定驗證型別
///
///
public bool IsContainsOperationType(string validateOperationType)
{
bool flag = false;
foreach (string item in validateOperationType.Split(’|’))
{
if (GetCurrentActionOperationType().Contains(item))
{
flag = true;
break;
}
}
return flag;
}

    /// <summary>
    /// 當前請求Action的方法裡是所有的驗證操作型別
    /// </summary>
    /// <returns></returns>
    public List<string> GetCurrentActionOperationType()
    {
        List<string> Operation = new List<string>();
        //得到當前Controller
        string controllerName = System.Web.HttpContext.Current.Request.RawUrl.Split('/')[1];
        //得到當前Action
        string actionName = System.Web.HttpContext.Current.Request.RawUrl.Split('/')[2];
        if (!string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName))
        {
            //反射載入控制器類
            Type type = Type.GetType("MVC_GaoJi.Controllers." + controllerName + "Controller");
            //載入Action的方法
            MethodInfo method = type.GetMethod(actionName);
            //獲取方法裡面所有的OperationTypeAttribute 特性類 
            object[] attributes = method.GetCustomAttributes(typeof(ValidateOperationTypeAttribute), true);
            if (attributes.Any())
            {
                //迭代特性類裡面的所有屬性
                foreach (object item in attributes)
                {
                    PropertyInfo pi = item.GetType().GetProperties().FirstOrDefault(x => x.Name == "OperationType");
                    if (pi != null)
                    {
                        Operation.Add(pi.GetValue(item, null).ToString());
                    }

                }
            }
        }
        return Operation;
    }
}

}

Code:2

public class ValidateOperationTypeAttribute : Attribute
{
public string OperationType { get; set; }
public ValidateOperationTypeAttribute(string operationType)
{
this.OperationType = operationType;
}
}

code:3 具體的重寫特性類 目前我就重寫了非空和正則表示式的特性 其他的可以自己擴充套件

namespace System.ComponentModel.DataAnnotations
{
public class MGRequiredAttribute : RequiredAttribute
{
private MyValidateHelper helper { get; set; }
public MGRequiredAttribute()
{
helper = new MyValidateHelper();
}
public string ValidateOperationType { get; set; }
public override bool IsValid(object value)
{
if (helper.IsContainsOperationType(ValidateOperationType))
{
if (value != null)
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}

}

public class MGRegularExpression : RegularExpressionAttribute
{
    private string patter { get; set; }
    private MyValidateHelper helper { get; set; }
    public MGRegularExpression(string pattern)
        : base(pattern)
    {
        patter = pattern;
        helper = new MyValidateHelper();
    }
    public string ValidateOperationType { get; set; }
    public override bool IsValid(object value)
    {

        if (helper.IsContainsOperationType(ValidateOperationType))
        {
            if (value != null)
            {
                return Regex.IsMatch(value.ToString(), patter);
            }
            else
            {
                return true;
            }
        }
        else
        {
            return true;
        }
    }
}

code:4 Model類如何加特性

///
/// 使用者名稱
///
[DisplayName(“使用者名稱”)]
[MGRequired(ErrorMessage = “使用者名稱不能為空”, ValidateOperationType = “Add|Update”)]
public string Name { get; set; }
///
/// 密碼
///
[DisplayName(“密碼”)]
public string Pwd { get; set; }
///
/// 賬號
///
[DisplayName(“賬號”)]
[MGRequired(ErrorMessage = “賬號不能為空”, ValidateOperationType = “Add|Update”)]
[MGRegularExpression(@"([a-zA-Z0-9_.-])[email protected](([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,5})+", ErrorMessage = “必須是郵箱型別”, ValidateOperationType = “Add|Update”)]
public string AccountNo { get; set; }
///
/// 年齡
///
[DisplayName(“年齡”)]
public string Age { get; set; }
///
/// 性別
///
[DisplayName(“性別”)]
public int Sex { get; set; }

Code:5 Action加特性

[ValidateOperationType("Add")]
    public ActionResult Add(CLModel cl)
    {
        bool flag = ModelState.IsValid;
        return Json(true);
    }

    [ValidateOperationType("Update")]
    public ActionResult Update(CLModel cl)
    {
        bool flag = ModelState.IsValid;
        return Json(true);
    }