zoukankan      html  css  js  c++  java
  • 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 == nullthrow new ArgumentNullException("helper");
                
    if (selectList == nullthrow 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
    <stringobject>(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 { getset; }

            
    public int MaxSelected { getset; }

            
    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();
    };
  • 相关阅读:
    数据驱动ddt简单使用
    html-testRunner在unittest测试套件中的使用
    Python设计模式----3.单例模式
    Python设计模式----2.工厂模式
    Python设计模式----1.简单工厂模式
    在小程序中对图片进行缩放时发生的问题记录
    将项目发布到Maven中央仓库的不完整纪要
    虚机的SQL Server空间占满之后进行释放的一些操作
    jdk8环境下,添加重复注解的美好体验
    使用transient关键字解决ehcache序列化错误
  • 原文地址:https://www.cnblogs.com/xianhong/p/2023831.html
Copyright © 2011-2022 走看看