• Asp.net Mvc自定义客户端验证(CheckBox列表的验证)


    最近在使用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();
    };

  • 相关阅读:
    h5之js生成二维码
    h5手势密码开发(使用jq)
    html可用于跨域的三个标签
    原生js实现ajax
    js中parentNode,parentElement,childNodes,children
    js字符串操作之substr与substring
    pyhton之os.path
    [bzoj1510][POI2006]Kra-The Disks_暴力
    [bzoj4994][Usaco2017 Feb]Why Did the Cow Cross the Road III_树状数组
    [bzoj2506]calc_分块处理
  • 原文地址:https://www.cnblogs.com/hyl8218/p/2074881.html
Copyright © 2020-2023  润新知