Asp.net Mvc自訂用戶端驗證(CheckBox列表的驗證)

來源:互聯網
上載者:User

最近在使用MVC進行開發時,使用進行用戶端的輸入驗證,加上使用MVC3的新視圖引擎感覺還是挺方便的,不用自己去寫很多js了,並且效果也能讓人接受

可是遇上要向外輸出比如一個CheckBox列表時就糾結了,驗證代碼還得自己去寫,這樣就造成了用戶端採用了兩套驗證,感覺不統一也不優雅,於是就琢磨了一下,便有了如下實現方式。

HtmlHelper的擴充類主要包括CheckBoxList,CheckBoxListFor等方法,有了這些方法,你可以這樣產生checkBox 列表

@Html.CheckBoxListFor(m=>m.RoleList,"li")

 下來就是擴充的全部代碼

HtmlHelperExtention.cs
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;

namespace Newborn.BSCommon
{
    /// <summary>
    /// HtmlHelper擴充
    /// </summary>
    public static class HtmlHelperExtention
    {
        public static MvcHtmlString InputList(this HtmlHelper helper, IEnumerable<SelectListItem> selectList, string checkBoxName, string splitTagName, InputType inputType)
        {
            return InputList(helper, null, selectList, checkBoxName,splitTagName, inputType);
        }

        /// <summary>
        /// 產生CheckBox列表
        /// </summary>
        /// <param name="helper">HtmlHelper</param>
        /// <param name="checkBoxName">name屬性</param>
        /// <param name="splitTagName">每個SelectList外層</param>
        /// <param name="inputType">inputType</param>
        /// <param name="selectList">selectList</param>
        /// <param name="metadata">metadata</param>
        /// <returns>MvcHtmlString</returns>
        public static MvcHtmlString InputList(this HtmlHelper helper,ModelMetadata metadata, IEnumerable<SelectListItem> selectList, string checkBoxName, string splitTagName, InputType inputType)
        {
            if (helper == null) throw new ArgumentNullException("helper");
            if (selectList == null) throw new ArgumentNullException("selectList");
            if (string.IsNullOrEmpty(checkBoxName)) throw new ArgumentNullException("checkBoxName");
           
            StringBuilder sb = new StringBuilder();
            int idIndex = 0;
            TagBuilder tagBuilder = new TagBuilder("span");
            foreach (SelectListItem item in selectList)
            {
                TagBuilder splitTagBuilder = null;
                if (!string.IsNullOrEmpty(splitTagName))
                    splitTagBuilder = new TagBuilder(splitTagName);
                TagBuilder checkTagBuilder = new TagBuilder("input");
                checkTagBuilder.Attributes["type"] = inputType.ToString();
                checkTagBuilder.Attributes["name"] = checkBoxName;
                checkTagBuilder.Attributes["value"] = item.Value;

                string checkBoxId = checkBoxName + "_id_" + idIndex;
                checkTagBuilder.Attributes["id"] = checkBoxId;
                if (item.Selected)
                    checkTagBuilder.Attributes["checked"] = "checked";
                TagBuilder labelTagBuilder = new TagBuilder("label") { InnerHtml = helper.Encode(item.Text) };

                labelTagBuilder.Attributes["for"] = checkBoxId;
                string checkHtml = checkTagBuilder.ToString() + labelTagBuilder.ToString();
                if (splitTagBuilder != null)
                {
                    splitTagBuilder.InnerHtml += checkHtml;
                    sb.AppendLine(splitTagBuilder.ToString());
                }
                else
                    sb.AppendLine(checkHtml);

                idIndex++;
            }
           
            TagBuilder hiddenTagBuilder = new TagBuilder("input");
            hiddenTagBuilder.Attributes["type"] = "hidden";
            hiddenTagBuilder.MergeAttribute("name", checkBoxName);
            hiddenTagBuilder.MergeAttribute("id", "hidden"+ checkBoxName);
            hiddenTagBuilder.MergeAttributes<string, object>(helper.GetUnobtrusiveValidationAttributes(checkBoxName, metadata));
            tagBuilder.InnerHtml = hiddenTagBuilder + sb.ToString();
            return MvcHtmlString.Create(tagBuilder.ToString());
        }
        /// <summary>
        /// 產生CheckBox列表
        /// </summary>
        /// <param name="helper">HtmlHelper</param>
        /// <param name="selectList"></param>
        /// <param name="checkBoxName">name屬性</param>
        /// <returns>MvcHtmlString</returns>
        public static MvcHtmlString CheckBoxList(this HtmlHelper helper, IEnumerable<SelectListItem> selectList, string checkBoxName)
        {
            return helper.InputList(selectList, checkBoxName, null, InputType.CheckBox);
        }

        public static MvcHtmlString InputListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,string splitTag,InputType inputType)
        {
            ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
            List<SelectListItem> list = ((List<SelectListItem>)modelMetadata.Model);
            return htmlHelper.InputList(modelMetadata, list, modelMetadata.PropertyName, splitTag, inputType);
        }
        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return htmlHelper.InputListFor(expression, "span",InputType.CheckBox);
        }
        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,string splitTag)
        {
            return htmlHelper.InputListFor(expression, splitTag, InputType.CheckBox);
        }

        /// <summary>
        ///  產生CheckBox列表
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="selectList"></param>
        /// <param name="checkBoxName"></param>
        /// <param name="splitTagName">每項分隔字元的Tag名稱</param>
        /// <returns></returns>
        public static MvcHtmlString CheckBoxList(this HtmlHelper helper, IEnumerable<SelectListItem> selectList, string checkBoxName, string splitTagName)
        {
            return InputList(helper, selectList, checkBoxName, splitTagName, InputType.CheckBox);
        }

 

        public static MvcHtmlString RadioBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return htmlHelper.InputListFor(expression, "span", InputType.Radio);
        }

       

        /// <summary>
        /// 產生RadioButton列表
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="selectList"></param>
        /// <param name="checkBoxName"></param>
        /// <param name="splitTag"></param>
        /// <returns></returns>
        public static MvcHtmlString RadioButtonList(this HtmlHelper helper, IEnumerable<SelectListItem> selectList, string checkBoxName, string splitTag)
        {
            return InputList(helper, selectList, checkBoxName, splitTag, InputType.Radio);
        }

        /// <summary>
        /// 產生RadioButton列表
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="selectList"></param>
        /// <param name="checkBoxName"></param>
        /// <returns></returns>
        public static MvcHtmlString RadioButtonList(this HtmlHelper helper, IEnumerable<SelectListItem> selectList, string checkBoxName)
        {
            return InputList(helper, selectList, checkBoxName, null, InputType.Radio);
        }
    }
}
 由於使用到用戶端驗證所以要引用如下的js檔案。

指令碼部分

<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/Custom/jquery.validate.unobtrusive.extension.js")" type="text/javascript"></script>
<script type="text/javascript">
      $(function () {
           new checkBoxList("RoleList", "hiddenRoleList");//初始驗證
      });
</script>
頁面上還要寫這個一句

 $(function () {
           new checkBoxList("RoleList", "hiddenRoleList");//初始驗證

      });

 是為了讓指令碼去綁定事件,可能還會有更好的方式,這裡有待研究。

頁面上代碼如下:

HTML部分

<div class="select">    
    @Html.CheckBoxListFor(m=>m.RoleList,"li")
    @Html.ValidationMessageFor(m => m.RoleList)
</div>
ListSlectRangeAttribute.cs 檔案

View Code
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace Newborn.BSCommon
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
    public class ListSlectRangeAttribute : ValidationAttribute, IClientValidatable
    {
        private const string errFormat = "該項最少選擇項為{0}最多選擇項為{1}";

        public ListSlectRangeAttribute()
        {
            MinSelected = 0;
            MaxSelected = -1;
        }

        public int MinSelected { get; set; }

        public int MaxSelected { get; set; }

        public override bool IsValid(object value)
        {
            return true;
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(errFormat, MinSelected > 0 ? MinSelected.ToString() : "不限", MaxSelected > 0 ? MaxSelected.ToString() : "不限");
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule rule = new ModelClientValidationRule
            {
                ValidationType = "list",
                ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
            };
            rule.ValidationParameters["min"] = MinSelected;
            rule.ValidationParameters["max"] = MaxSelected;

            yield return rule;
        }
    }
}
jquery.validate.unobtrusive.extension.js檔案主要完成用戶端如checkbox列表的驗證,細心的朋友會發現因為checkbox列表是多個input所以我沒有基於它來做,而是採用一個隱藏欄位還記錄現在選擇的項數目(目前只記錄選擇了多少項,沒記錄選擇的項值之類的,不過目前暫無此類需求,如果有擴充起來也行方便)。
//by xianhong
//添加驗證如驗證框必須選擇一定數量的驗證
$.validator.addMethod("maxminselected", function (value, element, param) {
    var min = param[0];
    var max = param[1];
    if (value >= min && (max <= 0 || value <= max))
        return true;
    return false;
});
$.validator.unobtrusive.adapters.addMinMax("list", "min", "max", "maxminselected");

var checkBoxList = function (name/*input name屬性*/, hiddenId/*記錄選擇的隱藏欄位*/) {
    this.checkedCount = function () {
        var selected = $("input[name='" + name + "']:checked");
        return selected.length;
    };
    this.All = function () {
        return $("input[name='" + name + "']");
    };
    this.BindClick = function () {
        var thisobj = this;
        this.All().click(function () {
            $("#" + hiddenId).val(thisobj.checkedCount());
        });
    };
    this.BindClick();
};

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.