前面几篇文章介绍了一下ASP.NET MVC中的一些基础,今天我们一起来学习一下在ASP.NET MVC中控件的封装。在页面中我们会经常使用到Html对象,来程序控件,当然这里的控件不是说ASP.NET中包含很多ViewState或其他信息的控件。在ASP.NET MVC中控件就是扩展方法,主要对HtmlHelper实例的扩展,不过这里主要会提到CheckBoxList和RadioButtonList的扩展,因为在微软自带的控件中是没有这两个控件存在的,所以我们需要自己扩展。最后还会介绍一下,Html.CheckBoxFor这个控件在使用时会有两个值,在服务端进行判断的结果。

ASP.NET MVC(包含MVC3.0,MVC4.0)中的控件都在System.Web.Mvc中,这里需要了解一下HtmlMvcString和普通的string的区别。在我看来HtmlMvcString就是对string进行编码,使得浏览器能够正确解析HTML字符串。这样在前台显示时就不需要使用Html.Raw方法对字符串进行编码,否则显示的字符串将不会解析成HTML代码。这个只需了解就可以了,有兴趣可以试试就知道所以然了,所以MVC控件都需要返回这个对象。

在ASP.NET MVC中,lumbda表达式是很经常用的,而且非常好用。在页面中声明了一个模型,那样就可以使用lumbda表达式进行实例的赋值和判断,当然在对控件扩展时就会预见到表达式的使用,这些都是.NET3.5的特性,这里就不多赘述。

/// <summary>
         /// 复选框扩展。
         /// </summary>
         /// <typeparam name="TModel">模型类型。</typeparam>
         /// <typeparam name="TProperty">属性类型。</typeparam>
         /// <param name="helper">HTML辅助方法。</param>
         /// <param name="expression">lambda表达式。</param>
         /// <param name="selectList">选择项。</param>
         /// <param name="htmlAttributes">HTML属性。</param>
         /// <returns>返回复选框MVC的字符串。</returns>
         public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, ButtonFormatter formatter = ButtonFormatter.Horizontal, IDictionary<string, object> htmlAttributes = null)
         {
             if(selectList == null || expression == null)
                 return MvcHtmlString.Empty;
             string name = ExpressionHelper.GetExpressionText(expression);
             List<string> values = null;
             object obj = helper.ViewData.Eval(name);
             if(obj != null)
                 values = obj.ToString().Split<string>();
             else
                 values = new List<string>();
 
             StringBuilder sb = new StringBuilder();
             int index = 0;
             foreach(var item in selectList)
             {
                 TagBuilder tag = new TagBuilder("input");
                 tag.MergeAttributes<string, object>(htmlAttributes);
                 tag.MergeAttribute("type", "checkbox", true);
                 tag.MergeAttribute("name", name, true);
                 tag.MergeAttribute("id", name + index, true);
                 tag.MergeAttribute("value", item.Value, true);
                 if(values.Contains(item.Value))
                     tag.MergeAttribute("checked", "checked", true);
                 sb.AppendLine(tag.ToString(TagRenderMode.SelfClosing) + " ");
                 TagBuilder label = new TagBuilder("label");
                 label.MergeAttribute("for", name + index);
                 label.InnerHtml = item.Text;
                 sb.AppendLine(label.ToString());
                 if(formatter == ButtonFormatter.Vertical)
                     sb.AppendLine("<br />");
                 index++;
             }
             return new MvcHtmlString(sb.ToString());
         }
 
         /// <summary>
         /// 复选框扩展。
         /// </summary>
         /// <typeparam name="TModel">模型类型。</typeparam>
         /// <typeparam name="TProperty">属性类型。</typeparam>
         /// <param name="helper">HTML辅助方法。</param>
         /// <param name="expression">lambda表达式。</param>
         /// <param name="selectList">选择项。</param>
         /// <param name="htmlAttributes">HTML属性。</param>
         /// <returns>返回复选框MVC的字符串。</returns>
         public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, ButtonFormatter formatter, object htmlAttributes)
         {
             return helper.CheckBoxListFor<TModel, TProperty>(expression, selectList, formatter, new RouteValueDictionary(htmlAttributes));
         }
 
         /// <summary>
         /// 枚举复选框扩展。
         /// </summary>
         /// <typeparam name="TModel">模型类型。</typeparam>
         /// <typeparam name="TProperty">属性类型。</typeparam>
         /// <param name="helper">HTML辅助方法。</param>
         /// <param name="expression">lambda表达式。</param>
         /// <param name="selectList">选择项。</param>
         /// <param name="htmlAttributes">HTML属性。</param>
         /// <returns>返回复选框MVC的字符串。</returns>
         public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, ButtonFormatter formatter = ButtonFormatter.Horizontal, object htmlAttributes = null, string classKey = Globals.Resource)
         {
             var selectList = new List<SelectListItem>();
             Globals.ForEach<TProperty>(p => {
                 selectList.Add(new SelectListItem { Text = Globals.GetGlobalResourceByKey(p, classKey), Value = p.ToString() });
             });
             return helper.CheckBoxListFor<TModel, TProperty>(expression, selectList, formatter, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

上面的代码各位有需要可以直接复制编译后就可以使用了,其他涉及的资源的可以修改一下。而ButtonFormatter是一个枚举类,主要用于设计横排还是竖排的样式,其他没什么作用。这样我们就可以很快的再前台使用CheckBoxList控件了,注意不是所有的页面都有模型,或者说不是所有CheckBoxList都可以使用lumbda表达式来进行赋值等设置的,所以最好扩展一下CheckBoxList控件,那样在各种情况都可以使用。

以上是我早期扩展的一个控件,其实很多地方都可以改的,比如属性转换,匿名类型可以直接实例化为RouteValueDictionary的,他的构造函数里就有这个。其中Globals.ForEach是我对枚举迭代的一个扩展,即是循环枚举中的每一个值显示出来。而RadioButtonList的扩展和CheckBoxList的扩展是差不多的,只要标记替换一下就可以了,不过在大部分情况下比较少用,因为很多地方都被DropDownList替代。

下面介绍一下在使用CheckBox时,服务端获取是否选中的方法。假如你使用过这个控件就会发现,呈现的HTML代码中包含两个checkbox的input,只是其中一个被隐藏了,当我们使用submit按钮提交时,在服务端获得的值就会包含两个input的值。为了解决这个问题,我们需要判断一下到底有没有被选中,不难发现,如果没有被选中,这服务端获取得到的值就只有一个False的值,如果选中了就会有两个,一个True一个False,所以我们需要判断到底服务端获得的第一个值是False还是True,具体代码可以看下面。

/// 判断是否被选中。
         /// </summary>
         /// <param name="form">路由实例对象。</param>
         /// <param name="key">路由键。</param>
         /// <param name="defaultValue">返回默认值。</param>
         /// <returns>返回是否被选中。</returns>
         public static bool IsChecked(this FormCollection form, string key, bool defaultValue = false)
         {
             var values = form.GetValues(key);
             if(values!=null)
                 return values[0].To<bool>(defaultValue);
             return defaultValue;
         }
 
         /// <summary>
         /// 判断是否被选中。
         /// </summary>
         /// <param name="request">路由实例对象。</param>
         /// <param name="key">路由键。</param>
         /// <param name="defaultValue">返回默认值。</param>
         /// <returns>返回是否被选中。</returns>
         public static bool IsChecked(this HttpRequestBase request, string key, bool defaultValue = false)
         {
             var values = request.Form.GetValues(key);
             if(values != null)
                 return values[0].To<bool>(defaultValue);
             return defaultValue;
         }

跟我一起学习ASP.NET 4.5 MVC4.0(五)(转)的更多相关文章

  1. 跟我一起学习ASP.NET 4.5 MVC4.0(二)

    上一篇文章中(跟我一起学习ASP.NET 4.5 MVC4.0(一))我们基础的了解了一下ASP.NET MVC4.0的一些比较简单的改变,主要是想对于MVC3.0来说的.因为这一些列主要是要给ASP ...

  2. 跟我一起学习ASP.NET 4.5 MVC4.0(一)

    跟我一起学习ASP.NET 4.5 MVC4.0(一)   由于上面一个项目使用的是ASP.NET4.0 MVC3.0,在招人的时候发现很多人有听说过MVC,但是却是没用过,对MVC也只是一知半解,最 ...

  3. 跟我一起学习ASP.NET 4.5 MVC4.0 (转)

    跟我一起学习ASP.NET 4.5 MVC4.0(一)   由于上面一个项目使用的是ASP.NET4.0 MVC3.0,在招人的时候发现很多人有听说过MVC,但是却是没用过,对MVC也只是一知半解,最 ...

  4. 跟我一起学习ASP.NET 4.5 MVC4.0(一)(转)

    由于上面一个项目使用的是ASP.NET4.0 MVC3.0,在招人的时候发现很多人有听说过MVC,但是却是没用过,对MVC也只是一知半解,最近想给团队成员做一个系统的解说,让大家都可以学习一下ASP. ...

  5. 跟我一起学习ASP.NET 4.5 MVC4.0(五)

    前面几篇文章介绍了一下ASP.NET MVC中的一些基础,今天我们一起来学习一下在ASP.NET MVC中控件的封装.在页面中我们会经常使用到Html对象,来程序控件,当然这里的控件不是说ASP.NE ...

  6. 跟我一起学习ASP.NET 4.5 MVC4.0(六)(转)

    这一系列文章跨度有点大,由于最近忙于其他事情,没有更新,今天重新安装了下Win8系统,VS2012和SQLServer 2012,顺便抽空继续一篇.随着VS2012 RC版本的放出,ASP.NET M ...

  7. 跟我一起学习ASP.NET 4.5 MVC4.0(四)(转)

    前几个文章中介绍了一些关于MVC4.0的东东,今天我们来看一下登陆验证,也可以说是权限验证,即AuthorizeAttribute.这个可以使用在控制器Controller上,也可以使用在Action ...

  8. 跟我一起学习ASP.NET 4.5 MVC4.0(三)(转)

    今天我们继续ASP.NET 4.5 MVC 4.0,前两天熟悉了MVC4.0在VS11和win8下的更新,以及MVC中的基础语法和几个关键字的使用.了解了这些就可以对MVC进一步认识,相信很多人都对M ...

  9. 跟我一起学习ASP.NET 4.5 MVC4.0(六)

    这一系列文章跨度有点大,由于最近忙于其他事情,没有更新,今天重新安装了下Win8系统,VS2012和SQLServer 2012,顺便抽空继续一篇.随着VS2012 RC版本的放出,ASP.NET M ...

随机推荐

  1. GlusterFS创建volume失败的解决方法(* or a prefix of it is already part of a volume)

    问题描写叙述: 之前已经创建了一个replicated的volume gv0,replica=2,两个文件夹为:/test/data1和/test/data2,之后发现这两个文件夹不太合适,想在/te ...

  2. ORA-01489: result of string concatenation is too long

    ORA-01489: result of string concatenation is too long Cause: String concatenation result is more tha ...

  3. DES加密解密(适用Windows和Linux系统)防止linux下解密失败

    转自:http://blog.csdn.net/jerry_bj/article/details/8276552 package com.lasun.util; import java.io.File ...

  4. 2sum、3sum、4sum以及任意连续的数的和为sum、任意连续或者不连续的数的和为sum

    2sum 如果数组是无序的,先排序(n*logn),然后用两个指针i,j,各自指向数组的首尾两端,令i=0,j=n-1,然后i++,j--,逐次判断a[i]+a[j]?=sum,如果某一刻a[i]+a ...

  5. 基于jQuery上下切换的焦点图—带缩略图悬浮

    分享一款基于jQuery上下切换的焦点图,这款焦点图带有缩略图悬浮,它的切换效果比较简单,仅仅是作图片的上下切换,但是效果还是比较流畅的.这款jQuery焦点图插件的另外一个特点是在播放器上面可以悬浮 ...

  6. 基于jQuery美化联动下拉选择框

    今天给大家介绍一款基于jQuery美化联动下拉选择框.这款下下拉选择框js里自带了全国所有城市的数数库.下拉选择框适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲 ...

  7. Javascript操纵Cookie--转

    引用地址:http://www.imkevinyang.com/2009/06/javascript%E6%93%8D%E7%BA%B5cookie.html 在讲如何使用Javascript操纵Co ...

  8. python 接口测试 、提交数据

    在测试过程中经常会遇见需要向服务器提交数据.或者进行接口测试,这个有很多方法,但是我经常用的就是使用python 编写脚本提交,方便.说说方法: 思路: 1.首先有一个提交数据的url 2.按照字典的 ...

  9. 客户端动态化系列之——Weex

    来源:kuailejim 链接:http://www.jianshu.com/p/ea25fd834944 客户端动态化系列之--URLRoute 在前端越来越火的年代,逐渐衍生出类似React Na ...

  10. BootStrap2学习日记17---导航路径和分页

    导航路径 代码: <ul class="breadcrumb"> <li><a href="#">Home</a> ...