分享

ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法

 weijianian 2016-08-07

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


1.1 有失必有得



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


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


' />


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


1.2 HtmlHelper初窥


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


<%: Html.Raw('

Hello,I am HtmlHelper!

') %>


那么,为什么可以在页面中调用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},于是我们项目中所有的标签所指向的都是以刚刚的规则命名的href(例如:)。但是在第二版中,我们的路由规则也会变成了{controller}-{action}-{id},那么我们刚刚为超链接所设置的href便都无法正常访问了。这时,我们需要进行替换,单个替换或批量替换(例如改为:),虽然也可以解决问题,但是无疑增加了工作量,效率很低。

那么,怎样来屏蔽这种变化所带来的不便呢?这里,通过使用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' })


其生成的结果为:


这是一个连接

带有QueryString的写法
这是一个连接
这是一个连接
有其它Html属性的写法
这是一个连接
这是一个连接
QueryString与Html属性同时存在
这是一个连接

这是一个连接


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


(2)TextBox与TextArea

①TextBox


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


其生成的结果为:






②TextArea


Html.TextArea('input5', Model.CategoryName, 3, 9,null)

Html.TextAreaFor(a => a.CategoryName, 3, 3, null)


其生成的结果为:




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


(3)CheckBox


Html.CheckBox('chk1',true)

Html.CheckBox('chk1', new { @class='checkBox'})

Html.CheckBoxFor(a =>a.IsVaild, new { @class = 'checkBox' })


其生成的结果为:





(4)DropDownList


Html.DropDownList('ddl1', (SelectList)ViewData['Categories'], '--Select One--')

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


其生成的结果为:




(5)RadioButton


男<%: Html.RadioButton('Gender','1',true) %>

女<%: Html.RadioButton('Gender','2',false) %>


其生成的代码为:




(6)Encode与Raw


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


<%: Html.Encode('

哈哈

') %>


其生成的代码为:


<p>哈哈</p>


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


<%: Html.Raw('

哈哈

') %>


其生成的代码为:


哈哈


在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('Hello-{0}-End', value));

}


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


namespace System.Web.Mvc


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


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

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


<%: Html.MyExtHtmlLabel('EdisonChou') %>


(5)查看页面效果


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多