前面几篇文章介绍了一下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. Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE]

    在Android studio中想要运行程序,点击运行后程序安装失败,报出如下异常: 原因:在manifest中设置了 .android:sharedUserId="android.uid. ...

  2. 使用RemObjects Pascal Script (转)

    http://www.cnblogs.com/MaxWoods/p/3304954.html 摘自RemObjects Wiki 本文提供RemObjects Pascal Script的整体概要并演 ...

  3. 【M17】考虑使用缓式评估

    1.缓式评估其实就是拖延战术,直到逼不得已的时候才去计算.缓式评估的使用场景有: 2.引用计数,考虑String,String是一个内含char指针(char指针以'\0'结束)的资源管理类,正常情况 ...

  4. C# 程序员最常犯的 10 个错误

    关于C# C#是达成微软公共语言运行库(CLR)的少数语言中的一种.达成CLR的语言可以受益于其带来的特性,如跨语言集成.异常处理.安全性增强.部件组合的简易模型以及调试和分析服务.作为现代的CLR语 ...

  5. ProgressCircular

    https://github.com/eltld/ProgressCircular

  6. 【JavaScript】jQuery Ajax 实例 全解析

    jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是对 ...

  7. Python之美[从菜鸟到高手]--深刻理解原类(metaclass)

    本来想自己写这篇文章的,可当我读了这篇文章http://blog.jobbole.com/21351/,我打消了这个念头,因为肯定写的没有人家的好,说的通俗易懂,面面俱到.就厚着面皮修改下格式,测试下 ...

  8. crm2011创建货币Money类型的字段

    using System;     using Microsoft.Xrm.Sdk;     using Microsoft.Xrm.Sdk.Messages;     using Microsoft ...

  9. char *a 与char a[] 的区别

    原文:http://www.cnblogs.com/kaituorensheng/archive/2012/10/23/2736069.html char *a = "hello" ...

  10. 深入理解 iOS 开发中的锁

    来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大 ...