背景html
因爲MVC的前端是基於jquery.validate和jquery.validate.unobtrusive來實現的,可是當咱們要使用其餘的ui組件且組件自己就帶有完整的驗證功能的話,那麼要讓它們配合起來是有些麻煩的,好比:easyui。前端
介紹jquery
MVC主要提供了一下幾個驗證特性來支撐前端的驗證: 正則表達式
以上大部分來自System.ComponentModel.DataAnnotations.dll,最後2個是來自System.Web.Mvc.dllexpress
而easyui則是基於validatebox可自定義驗證規則以及派生出datebox、numberbox、combobox等控件,來實現form表單輸入控件的一套完成的驗證體系(詳情可參考:www.jeasyui.com),easyui的驗證代碼以下:
mvc
<input class="easyui-validatebox validatebox-text" name="Name" required="true" missingmessage="用戶名不能爲空!" validtype="regular['^\\w+$', '用戶名格式不正確!']" value="admin" type="text">
實現ui
瞭解了以上的2方提供的驗證支持,那麼咱們就能夠將mvc提供的驗證解析爲支持easyui驗證的前端html代碼了,根據以上的資料咱們能夠發現如下幾個可直接轉換的規則,實現代碼大體以下:this
var attribute = validationAttrs.FirstOrDefault(attr => attr is RequiredAttribute); if (attribute != null) { tag.AddAttribute("required", "true"); tag.AddAttribute("missingMessage", attribute.ErrorMessage); } attribute = validationAttrs.FirstOrDefault(attr => !(attr is RequiredAttribute)); if (attribute == null) return; if (attribute is StringLengthAttribute) { var stringLengthAttr = attribute as StringLengthAttribute; tag.AddAttribute("invalidMessage", stringLengthAttr.ErrorMessage); tag.AddAttribute("validType", "length[{0}, {1}]", stringLengthAttr.MinimumLength, stringLengthAttr.MaximumLength); } else if (attribute is RegularExpressionAttribute) { var regularAttr = attribute as RegularExpressionAttribute; tag.AddAttribute("validType", "regular['{0}', '{1}']", regularAttr.Pattern.Replace("\\", "\\\\"), regularAttr.ErrorMessage); } else if (attribute is RangeAttribute) { var rangeAttr = attribute as RangeAttribute; tag.AddAttribute("validType", "range[{0}, {1}, '{2}']", rangeAttr.Minimum, rangeAttr.Maximum, rangeAttr.ErrorMessage); } else if (attribute is CompareAttribute) { var compareAttr = attribute as CompareAttribute; tag.AddAttribute("validType", "eq['[name={0}]', '{1}']", compareAttr.OtherProperty, compareAttr.ErrorMessage); }
以上代碼中把RequiredAttribute和其餘的驗證規則區分開來是由於RequiredAttribute會生成獨立的required="true",而其餘的驗證規則都是公用validType屬性的,至於js驗證規則內的regular、range、eq的驗證規則並非easyui內部提供的,而是額外進行擴展的,js代碼以下:spa
$.extend($.fn.validatebox.defaults.rules, { eq: { validator: function (value, param) { this.message = param[1]; return value == $(param[0]).val(); } }, range: { validator: function (value, param) { this.message = param[2]; return value >= param[0] && value <= param[1]; } }, regular: { validator: function (value, param) { this.message = param[1]; var reg = new RegExp(param[0]); return reg.test(value); } } });
有了以上這些生成規則之後,咱們就能夠經過擴展HtmlHelper<TModel>來實現相似@Html.EditorFor(model => model.Name)這樣的調用了,大體代碼以下(這裏以validatebox爲例):插件
public static MvcHtmlString ValidateText(this HtmlHelper htmlHelper, Expression<Func<TModel, object>> expression) { ModelMetadata modelMetadatum = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); PropertyInfo property = typeof(TModel).GetProperty(modelMetadatum.PropertyName); TagBuilder tag = new TagBuilder("input"); ValidationAttribute[] validationAttrs; if (property.TryGetAttributes(out validationAttrs)) { //請閱讀轉換規則代碼 } return MvcHtmlString.Create(tag.ToString()); }
有了以上基礎代碼以後,咱們就可使用@Html.ValidateText(m => m.Name)來建立基於easyui的驗證控件了。
效果
//類: public class AccountView { private string m_Name = null; [Required(ErrorMessage = "用戶名不能爲空!")] [RegularExpression(@"^\w+$", ErrorMessage = "用戶名格式不正確!")] [DisplayName("用戶名:")] public string Name { get { return m_Name; } set { m_Name = value; } } } //頁面: @Html.LabelFor(m => m.Name) @Html.ValidateText(m => m.Name)//生成的內容爲頂部easyui html示例代碼
正確:
必填提示:
驗證失敗:
結尾
以上即是今天全部內容了,後面還有其餘的擴展功能,敬請期待,謝謝各位!