一、一个功能强大的页面开发辅助类—HtmlHelper初步了解

1.1 有失必有得

在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归。所以抛弃之前的那种事件响应的模型,抛弃服务器端控件也理所当然。

但是,如果手写Html标签效率又比较低,可重用度比较低。这时,我们该怎样来提高效率呢?首先,经过上篇我们知道可以通过ViewData传递数据,于是我们可以写出以下的Html代码:

1
<input name="UserName" type="text" value="<%: ViewData["UserName"] %>" />

虽然以上代码可以解决问题,但是效率还是比较低,特别是在列表集合项较多的时候,工作量会比较大。那么,还有木有一种更好的方式呢?别急,微软已经为我们想好了策略。微软为开发人员快速开发前台页面提供了丰富的HtmlHelper的辅助类,辅助我们快速开发前台页面,也提供了可扩展的接口,前台页面的标签可以可以做到高度可重用

1.2 HtmlHelper初窥

我们可以通过在页面中通过Html.XXX来实现快速的Html标签编辑,并且可以方便地进行数据绑定。

1
<%: Html.Raw("<p>Hello,I am HtmlHelper!</p>") %>

那么,为什么可以在页面中调用Html.XXX方法呢?通过ILSpy反编译ViewPage页,我们可以看到原来在ViewPage下有一个HtmlHelper类型的属性-Html。(这下终于知道,为什么可以在页面中使用Html.xxxx()了)

那么这个HtmlHelper类又是一个什么类型的大神呢?继续反编译查看,在System.Web.Mvc命名空间下的HtmlHelper类型 如下图所示,经过MSDN大神的讲解,HtmlHelper支持在视图中呈现 HTML 控件。那我们看看在此类中有木有传说中的TextBox、CheckBox的方法呢?经查看,木有。

那么,我们为什么可以在页面中使用Html.TextBox()方法呢?这里就涉及到一个叫做“扩展方法”的东东了,HtmlHelper 类的扩展方法在System.Web.Mvc.Html 命名空间中。 这些扩展添加了用于创建窗体、呈现 HTML 控件、呈现分部视图、执行输入验证等功能的帮助器方法。那么,有关如何自定义扩展方法请参阅本文第三部分,这里先卖个关子,暂不介绍。

1.3 为什么使用HtmlHelper?

思考这样一个场景:我们的项目第一个版本中的路由规则是这样的{controller}/{action}/{id},于是我们项目中所有 的<a>标签所指向的都是以刚刚的规则命名的href(例如:<a href=’Home/User/1′></a>)。但是在第二版中,我们的路由规则也会变成了{controller}- {action}-{id},那么我们刚刚为超链接所设置的href便都无法正常访问了。这时,我们需要进行替换,单个替换或批量替换(例如改 为:<a href=’Home-User-1′></a>),虽然也可以解决问题,但是无疑增加了工作量,效率很低。

那么,怎样来屏蔽这种变化所带来的不便呢?这里,通过使用HtmlHelper为我们提供的ActionLink标签,便可以解决这个问题。因为 HtmlHelper是从服务器端自动帮你生成a标签,因此所生成的href会遵循目前的路由规则,也就帮我们屏蔽了变化,提高了工作效率。

二、没有服务器控件也能干大事—HtmlHelper重要方法介绍

PS:这里的实例均没有加<% %>或@符号,要运行请自行加上。

(1)ActionLink与RouteLink

1
2
3
4
5
6
7
8
9
10
Html.ActionLink("这是一个连接", "Index", "Home")
带有QueryString的写法
Html.ActionLink("这是一个连接", "Index", "Home", new { page=1 },null)
Html.ActionLink("这是一个连接", "Index", new { page=1 })
有其它Html属性的写法
Html.ActionLink("这是一个连接", "Index", "Home", new { id="link1" })
Html.ActionLink("这是一个连接", "Index",null, new { id="link1" })
QueryString与Html属性同时存在
Html.ActionLink("这是一个连接", "Index", "Home", new { page = 1 }, new { id = "link1" })
Html.ActionLink("这是一个连接", "Index" , new { page = 1 }, new { id = "link1" })

其生成的结果为:

1
2
3
4
5
6
7
8
9
10
<a href="/">这是一个连接</a>
带有QueryString的写法
<a href="/?page=1">这是一个连接</a>
<a href="/?page=1">这是一个连接</a>
有其它Html属性的写法
<a href="/?Length=4" id="link1">这是一个连接</a>
<a href="/" id="link1">这是一个连接</a>
QueryString与Html属性同时存在
<a href="/?page=1" id="link1">这是一个连接</a>
<a href="/?page=1" id="link1">这是一个连接</a>

RouteLink在用法几乎与ActionLink一致,这里就不再介绍,详情请参与MSDN;

(2)TextBox与TextArea

①TextBox

1
2
3
4
Html.TextBox("input1")
Html.TextBox("input2",Model.CategoryName,new{ @style = "width:300px;" })
Html.TextBox("input3", ViewData["Name"],new{ @style = "width:300px;" })
Html.TextBoxFor(a => a.CategoryName, new { @style = "width:300px;" })

其生成的结果为:

1
2
3
4
<input id="input1" name="input1" type="text" value="" />
<input id="input2" name="input2" style="width:300px;" type="text" value="Beverages" />
<input id="input3" name="input3" style="width:300px;" type="text" value="" />
<input id="CategoryName" name="CategoryName" style="width:300px;" type="text" value="Electronic" />

②TextArea

1
2
Html.TextArea("input5", Model.CategoryName, 3, 9,null)
Html.TextAreaFor(a => a.CategoryName, 3, 3, null)

其生成的结果为:

1
2
<textarea cols="9" id="input5" name="input5" rows="3">Electronic</textarea>
<textarea cols="3" id="CategoryName" name="CategoryName" rows="3">Electronic</textarea>

这里可以看到,我们可以使用强类型来生成Html标签,例如:Html.TextBoxFor(a => a.CategoryName, new { @style = “width:300px;” }),这里的CategoryName就是某个类型的属性。

(3)CheckBox

1
2
3
Html.CheckBox("chk1",true)
Html.CheckBox("chk1", new { @class="checkBox"})
Html.CheckBoxFor(a =>a.IsVaild, new { @class = "checkBox" })

其生成的结果为:

1
2
3
<input checked="checked" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />
<input class="checkBox" id="chk1" name="chk1" type="checkbox" value="true" /><input name="chk1" type="hidden" value="false" />
<input checked="checked" class="checkBox" id="IsVaild" name="IsVaild" type="checkbox" value="true" /><input name="IsVaild" type="hidden" value="false" />

(4)DropDownList

1
2
Html.DropDownList("ddl1", (SelectList)ViewData["Categories"],  "--Select One--")
Html.DropDownListFor(a => a.CategoryName, (SelectList)ViewData["Categories"], "--Select One--", new { @class = "dropdownlist" })

其生成的结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<select id="ddl1" name="ddl1">
<option value="">--Select One--</option>
<option value="1">Beverages</option>
<option value="2">Condiments</option>
<option selected="selected" value="3">Confections</option>
<option value="4">Dairy Products</option>
<option value="5">Grains/Cereals</option>
<option value="6">Meat/Poultry</option>
<option value="7">Produce</option>
<option value="8">Seafood</option>
</select>
<select class="dropdownlist" id="CategoryName" name="CategoryName">
<option value="">--Select One--</option>
<option value="1">Beverages</option>
<option value="2">Condiments</option>
<option value="3">Confections</option>
<option value="4">Dairy Products</option>
<option value="5">Grains/Cereals</option>
<option value="6">Meat/Poultry</option>
<option value="7">Produce</option>
<option value="8">Seafood</option>
</select>

(5)RadioButton

1
2
男<%: Html.RadioButton("Gender","1",true) %>
女<%: Html.RadioButton("Gender","2",false) %>

其生成的代码为:

1
2
男<input checked="checked" id="Gender" name="Gender" type="radio" value="1" />
女<input id="Gender" name="Gender" type="radio" value="2" />

(6)Encode与Raw

Encode会将内容进行编码话,因此,如果你的内容中含有Html标签的话那么会被解析成特殊字符,例如:

1
<%: Html.Encode("<p>哈哈</p>") %>

其生成的代码为:

1
&amp;lt;p&amp;gt;哈哈&amp;lt;/p&amp;gt;

这里主要是为了防止XSS攻击和恶意脚本,因此在MVC中,默认的<%: %>就实现了<%: Html.Encode() %>。但是,某些时候如果我们需要输出Html或JavaScript内容的字符串,这时我们可以使用HtmlHelper为我们提供的其他方法。 例如我们要输出刚刚那句话,我们可以如下使用:

1
<%: Html.Raw("<p>哈哈</p>") %>

其生成的代码为:

1
<p>哈哈</p>

在HtmlHelper中还提供了许多的扩展方法供我们方便创建Html,比如:BeginForm、EndForm等。关于其他的方法介绍,请自行搜索,这里不再一一赘述。

三、随时随地我也能扩展—HtmlHelper扩展方法简介

3.1 扩展方法简介

借助MSDN的介绍:“扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。”扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。我们可以回到第一部分对HtmlHelper的扩展类-InputExtension类上,它是对于HtmlHelper的扩展,那么怎么鉴别它是HtmlHelper的扩展呢?

3.2 扩展方法的三要素

(1)静态类

可以从上图看出,InputExtension首先是一个静态类;

(2)静态方法

既然是静态类,那么其所有的方法必然都是静态方法,例如:public static MvcHtmlString CheckBox();

(3)this关键字

可以从方法名定义中看出,第一个参数都是this HtmlHelper htmlHelper,代表对HtmlHelper类的扩展;

3.3 自定义扩展方法

(1)在Models文件夹下新建一个类,取名为:MyHtmlHelperExt

(2)将MyHtmlHelperExt设置为static,并写入以下的一个静态方法:

1
2
3
4
public static HtmlString MyExtHtmlLabel(this HtmlHelper helper, string value)
{
      return new HtmlString(string.Format("<span style='font-weight:bold;'>Hello-{0}-End</span>", value));
}

(3)确定满足了扩展方法的三要素之后,将命名空间改为:System.Web.Mvc。

1
namespace System.Web.Mvc

PS:为什么要改命名空间为System.Web.Mvc?

这是因为如果不改命名空间,我们要使用自定义的扩展方法需要在每个页面中引入Models(MyHtmlHelper所在的那个命名空间)这个命名 空间,为了防止重复的命名空间引入操作(想想我们使用Html.TextBox()不也没有引入命名空间么?),于是我们将命名空间与 HtmlHelper类所在的命名空间保持一致。

(4)在页面中我们就可以使用我们自己写的扩展方法了

1
<%: Html.MyExtHtmlLabel("EdisonChou") %>

(5)查看页面效果

参考文章

(1)马伦,《ASP.Net MVC视频教程》,http://bbs.itcast.cn/thread-26722-1-1.html

(2)oer,《HtmlHelper使用大全》,http://www.cnblogs.com/oer2001/archive/2013/03/19/2968475.html

(3)MSDN,《扩展方法(C#编程指南)》,http://technet.microsoft.com/zh-cn/bb383977

(4)MSDN,《HtmlHelper类(System.Web.Mvc)》,http://msdn.microsoft.com/zh-cn/library/system.web.mvc.htmlhelper(v=vs.108).aspx

ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法的更多相关文章

  1. ASP.Net MVC开发基础学习笔记:一、走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  2. ASP.Net MVC开发基础学习笔记(1):走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  3. ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法

    一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...

  4. ASP.Net MVC开发基础学习笔记:三、Razor视图引擎、控制器与路由机制学习

    一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...

  5. ASP.Net MVC开发基础学习笔记:四、校验、AJAX与过滤器

    一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...

  6. ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  7. ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  8. ASP.Net MVC开发基础学习笔记(4):校验、AJAX与过滤器

    一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...

  9. ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习

    一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...

随机推荐

  1. Java_内存管理String and Array

    题目1.指出下列程序运行的结果 ()public class Example { String str = new String("good"); char[] ch = { 'a ...

  2. [Linux] vim的高亮查找操作

    reference :  http://blog.chinaunix.net/uid-20732478-id-763411.html 使用了VIM这么久,却一直无法牢记一些基本的操作指令.今天查找一个 ...

  3. Spetember 5th 2016 Week 37th Monday

    No matter how far you may fly, never forget where you come from. 无论你能飞多远,都别忘了你来自何方. Stay true to you ...

  4. google关于ssh key的解释(转)转的google的wiki的

    SSH keys (简体中文)     SSH 密钥对可以让您方便的登录到 SSH 服务器,而无需输入密码.由于您无需发送您的密码到网络中,SSH 密钥对被认为是更加安全的方式.再加上使用密码短语 ( ...

  5. jvm分析

    是什么 jps   查看所有的jvm进程,包括进程ID,进程启动的路径等等. jstack   观察jvm中当前所有线程的运行情况和线程当前状态. 系统崩溃了?如果java程序崩溃生成core文件,j ...

  6. Qt5_简易画板_详细注释

    代码下载链接:  http://pan.baidu.com/s/1hsc41Ek 密码: 5hdg 显示效果如下: 代码附有详细注释(代码如下) /*** * 先新建QMainWindow, 项目名称 ...

  7. 第三章 C#循环与方法

    第一节1-For循环入门 语法: for(条件表达式) { 执行语句 } 练习: 第三章作业1.写一个程序打印100到200的值;2.写一个程序从10打印到1:3.写一个程序打印10到30之间的所有偶 ...

  8. NYOJ之喷水装置(一)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsUAAAJvCAIAAAAcLjvHAAAgAElEQVR4nO3drXLjzNaG4e8kzH0gof

  9. VS对路径的访问被拒绝

    问题:权限问题. 1.检查自己电脑账户.是否是Administrator.如果没有启用.在[我的电脑]——[管理]——[本地用户和组]——[用户]——[Administrator]——[属性启用] 2 ...

  10. poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   ...