zoukankan      html  css  js  c++  java
  • ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法

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

    1.1 有失必有得

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

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

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

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

    1.2 HtmlHelper初窥

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

    <%: 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

    复制代码
    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" })
    复制代码

      其生成的结果为:

    复制代码
    <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

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

      其生成的结果为:

    <input id="input1" name="input1" type="text" value="" />
    <input id="input2" name="input2" style="300px;" type="text" value="Beverages" />
    <input id="input3" name="input3" style="300px;" type="text" value="" />
    <input id="CategoryName" name="CategoryName" style="300px;" type="text" value="Electronic" />

      ②TextArea

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

      其生成的结果为:

    <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 = "300px;" }),这里的CategoryName就是某个类型的属性。

      (3)CheckBox

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

       其生成的结果为:

    <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

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

      其生成的结果为:

    复制代码
    <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

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

      其生成的代码为:

    男<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标签的话那么会被解析成特殊字符,例如:

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

      其生成的代码为:

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

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

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

      其生成的代码为:

    <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,并写入以下的一个静态方法:

    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。

    namespace System.Web.Mvc

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

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

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

    <%: 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

  • 相关阅读:
    949. Largest Time for Given Digits
    450. Delete Node in a BST
    983. Minimum Cost For Tickets
    16. 3Sum Closest java solutions
    73. Set Matrix Zeroes java solutions
    347. Top K Frequent Elements java solutions
    215. Kth Largest Element in an Array java solutions
    75. Sort Colors java solutions
    38. Count and Say java solutions
    371. Sum of Two Integers java solutions
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/5611032.html
Copyright © 2011-2022 走看看