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();
};

你可能感兴趣的:(checkbox)