ASP.NET MVC 重点教程一周年版 第九回 HtmlHelper

许多时候我们会遇到如下场景

在写一个编辑数据的页面时,我们通常会写如下代码

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

由前篇我们所讲的Helper演化,我们思考,对于这种代码我们是不是也可以用一个Helper来自动绑定数据呢

这当然是可以的,ASP.NET MVC提供了一个HtmlHelper用于生成有数据绑定的Html标签。

1.ActionLink

其中最常用的就是Html.ActionLink

1.1基本的使用方式

   1: <%=Html.ActionLink("这是一个连接", "Index", "Home")%>

在UrlRouting规则为默认规则的情况下,它生成的HTML代码为

   1: <a href="/">这是一个连接</a>

ActionLink中的三个参数分别为

  1. 显示的文字
  2. Action
  3. Controller

其中Controller可以省略,省略时指向同一Controller下的Action。

1.2ActionLink中QueryString与Html属性设置

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

其生成结果为:

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

这样就可以使用ActionLink生成近乎所有的地址连接了。

注意,如果连接中不涉及到action及controller就没有必要使用ActionLink,而是直接写HTML代码就可以了,例如

   1: <a href="#1">一章</a>
   2: <a href="javascript:void(0)" onclick="delete();">删除</a>

2.RouteLink

2.1与ActionLink

RouteLink与ActionLink相差无几,只是它的地址是由Route生成拿上面的例子

   1: <%=Html.ActionLink("这是一个连接", "Index", "Home")%>

来说,如果用RouteLink来写就是

   1: <%=Html.RouteLink("这是一个连接", new { controller="Home",action="Index"})%>

 

而带上QueryString以及Html属性的ActionLink

   1: <%=Html.ActionLink("这是一个连接", "Index" , new { page = 1 }, new { id = "link1" })%>

就可以这样来写

   1: <%=Html.RouteLink("这是一个连接", new { action = "index", page = 1 }, new { id="link1"})%>

 

其实就是用一个新建立的RouteValueDictionary的对象(new{}所实例化的对象将会等价转换为RouteValueDictionary)来替原来的Action,Controller字符串的单独指定。

2.2RouteLink使用Route规则

除了这些协同的用法,RouteLink还支持使用Route规则名来创建连接

例如我们在Global.asax文件中添加一个Route规则

   1: routes.MapRoute(
   2:     "about",//这是规则名
   3:     "about",//url
   4:     new {controller = "Home", action = "about"}
   5:     );

那么我们就可以使用这个Route规则

   1: <%=Html.RouteLink("关于", "about", new { })%>
   2: <%=Html.RouteLink("关于", "about", new { page = 1 })%>
   3: <%=Html.RouteLink("关于", "about", new { page = 1 }, new { id = "link1" })%>

来生成如下的HTML:

   1: <a href="/about">关于</a>
   2: <a href="/about?page=1">关于</a>
   3: <a href="/about?page=1" id="link1">关于</a>

 

3.表单

很多情况下是要生成表单元素的,正如文章开始所述,修改一个内容的情况下,我们可能要将数据与表单绑定。

3.1生成Form

我们当然可以使用纯的Html代码或UrlHelper来生成一个Form。

   1: <form action="/home/index" method="post">
   2: </form>
   1: <form action="<%=Url.Action("Index","Home")%>" method="post">
   2: </form>

但是因为是在HTML的属性中,所以还是难以维护,幸好ASP.NET MVC为我们提供了一个Helper,我们可以通过以下两种方式生成一个Form:

   1: <%using(Html.BeginForm("index","home",FormMethod.Post)){%>
   2: 表单内容
   3: <%} %>
   4: <%Html.BeginForm("index", "home", FormMethod.Post);//注意这里没有=输出%>
   5: 表单内容
   6: <%Html.EndForm(); %>

BeginForm方法类似于ActionLink的调用方式,所以ASP.NET MVC还提供了BeginRouteForm这种方法。

当然这里我们也可以使用new{}来为form的action增加querystring或HTML属性,方法与前面介绍的大同小异,参见方法列表即可。

 

3.2表单元素

ASP.NET MVC提供了多种表单元素的Helper。

其中包括:TextBox(类似input type=text,下面类似)、TextArea、DropDownList(select)、CheckBoxHidden、ListBox、Password、RadionButton。

注意:因为<input type=”submit” />一般情况下是不会绑定数据的所以ASP.NET MVC并未提供此Helper(曾经提供过在preview2之前)

如果我们想提供一个input type=text 它的name为t1则以下代码:

   1: <%=Html.TextBox("t1") %>

3.3表单元素绑定

如果我们想要让上文中的t1初始时就有一个值,比如 “重典”那么我们可以按以下方式

   1: <%=Html.TextBox("t1","重典") %>

如果数据是从数据库中读取,即得到数据是从Action中获取的,那么我们可以在Action中使用ViewData传递

Action:

   1: ViewData["name"]="重典";

View:

   1: <%=Html.TextBox("t1",ViewData["name"]) %>

 

以上方法看似简单,其实ASP.NET MVC为我们提供了更为简便的绑定方式---只要保证ViewData的Key与Helper所生成元素的name保持一致就可以自动绑定:

Action:

   1: ViewData["t1"]="重典";

View:

   1: <%=Html.TextBox("t1") %>

 

 

这样就可以自动绑定了

3.4列表数据显示与绑定

像TextBox这种值单一的数据比较容易,但是存在的数据比较多的DropDownList或ListBox应该怎么绑定数据及初始化值呢,我们来看看下面的例子:

Action:

   1: ViewData["sel1"] = new SelectList(
   2:     new[] {1, 2, 3} /*列表内容可以是数组*/
   3:     , 3 /*默认值,可以是从数据库读出的*/
   4:     );

View:

   1: <%=Html.DropDownList("sel1")%>

这样就可以将列表内容、默认值、以及表单元素三者绑定在一起了。

而我们的列表内容并不是任何情况下都是数组的,大多情况下还是Key-Value对居多。

我们可以使用以下方式:

   1: List<SelectListItem> list = new List<SelectListItem>
   2:                               {
   3:                                   new SelectListItem {Text = "重典", Value = "1"},
   4:                                   new SelectListItem {Text = "邹健", Value = "2"},
   5:                               };
   6: ViewData["sel1"] = new SelectList(
   7:     list /*列表内容可以是数组*/
   8:     , "2" /*默认值,可以是从数据库读出的*/
   9:     );
posted @ 2009-04-13 16:56 重典 阅读(11008) 评论(24) 编辑 收藏

 回复 引用 查看   
#1楼2009-04-16 09:17 | E_wait      
继续学习!支持重典!
 回复 引用 查看   
#2楼2009-04-18 23:26 | masterfy      
这个ASP.NET MVC系列不错,支持!感觉这个框架做一些基本的网站还是很方便的,真正作复杂些的WEB应用系统的时候不知道行不行?
 回复 引用 查看   
#3楼[楼主]2009-04-23 11:01 | 重典      
@masterfy
Web能做的,都行

 回复 引用 查看   
#4楼2009-04-24 17:11 | xcccb      
用了后一种方法做下拉框绑定时.出现的并不是我想要的效果.出现的是
<select id="sel1" name="sel1"><option>System.Web.Mvc.SelectListItem</option>
<option>System.Web.Mvc.SelectListItem</option>
</select>

并不是想要的
<select id="sel1" name="sel1"><option value="1">重典</option>
<option value="2" selected>邹健</option>
</select>

 回复 引用 查看   
#5楼2009-04-24 17:18 | xcccb      
呵呵..解决了.改成下面这样的写法就可以了.

ViewData["sel1"] = new SelectList(
list,
"Value" ,
"Text",
"2"
);

 回复 引用   
#6楼2009-04-27 22:05 | gameover[未注册用户]
@重典
.我现在在做个小东西.
..想在网页中显示图片.
.有两种方式..
一种是直接在在数据库中存图片
一种是存在本地文件夹中.
利用什么方式可以在VIEW显示出来.
.还有就是怎么上传呢.
在这个里面都没介绍的.
.HELP..

 回复 引用 查看   
#7楼[楼主]2009-04-28 09:10 | 重典      
@gameover
这两个都和传统的Web编程方式是一样的,没有什么不同
我之后会写一篇关于交互的,希望可以解释您的问题
旧版本的文章在这里http://www.cnblogs.com/chsword/archive/2008/03/14/1105535.html

 回复 引用 查看   
#8楼2009-05-11 21:32 | John Liu      
不错。很好。支持楼主。
 回复 引用   
#9楼2009-05-31 14:05 | snow123[未注册用户]
怎样让html.textBox 的文本框变为不可编辑呢
 回复 引用 查看   
#10楼[楼主]2009-05-31 15:35 | 重典      
@John Liu
with html:
<input readonly=readonly />
with Helper
Html.TextBox("name",null/*or value*/,new{ readonly="readonly"})

 回复 引用   
#11楼2009-06-07 22:53 | flier45[未注册用户]
刁难了,怎样在按一个按钮后,又将不可编辑的文本框变得可以编辑呢?比如多级联动常常碰到此类问题
 回复 引用 查看   
#12楼[楼主]2009-06-08 10:22 | 重典      
@flier45
使用JS,引用 Jquery
比如文本框Id是t1则
按钮的Click或Ajax返回事件中加入以下代码
$("#t1").attr("readonly","readonly");

 回复 引用 查看   
#13楼2009-06-18 11:56 | 传说中的宝玉      
Html.TextBox("name",null/*or value*/,new{ readonly="readonly"}) 这句话出错啊


编译器错误消息: CS1525: 无效的表达式项“readonly”

 回复 引用   
#14楼2009-06-26 10:54 | ddx[未注册用户]
请问:
<%=Html.ActionLink("这是一个连接", "Index", "Home")%>
显示连接时,如果Action有参数呢,写成这样:
<%=Html.ActionLink("这是一个连接", "Index/Params", "Home")%>
路由规则对其有影响没有?

谢谢!

 回复 引用 查看   
#15楼[楼主]2009-06-26 10:59 | 重典      
@ddx
传递方式不对,请看上面的2.1 带QueryString以及Html属性的ActionLink

 回复 引用   
#16楼2009-07-01 15:40 | jagx526[未注册用户]
有html.checkbox的详细用法吗?
 回复 引用 查看   
#17楼2010-03-16 13:53 | 撞破南墙      
引用xcccb:呵呵..解决了.改成下面这样的写法就可以了.
<br/>
<br/> ViewData["sel1"] = new SelectList(
<br/> list,
<br/> "Value" ,
<br/> "Text",
<br/> "2"
<br/> );


实践发现 不用 new 一个 SelectList
直接把
List<SelectListItem>类型的 list 赋值给 ViewData["sel1"]
也可以。

 回复 引用 查看   
#18楼2010-09-17 15:14 | 枯树昏鸦      
用htmlhelper有什么好处我还是不明白啊,我们的页面一般都是美工给的,难道要美工去写“Html.TextBox()”这样的代码吗????
 回复 引用 查看   
#19楼2010-12-11 18:47 | 微生物      
@枯树昏鸦
这是个问题,微软似乎没有考虑到这个问题,但是比如python的django框架一开始的设计理念就是views不需要特别复杂的编程水平就能写。

 回复 引用 查看   
#20楼2011-03-20 22:22 | jackdesk      
引用撞破南墙:
引用xcccb:呵呵..解决了.改成下面这样的写法就可以了.
<br/>
<br/> ViewData["sel1"] = new SelectList(
<br/> list,
<br/> "Value" ,
<br/> "Text",
<br/> "2"
<br/> );


实践发现 不用 new 一个 SelectList
直接把
List<SelectListItem>...

恩是的呢,试了下真的行

 回复 引用 查看   
#21楼2011-09-07 18:11 | 饼子天空      
1.2ActionLink中QueryString与Html属性设置
8: <%=Html.ActionLink("这是一个连接", "Test", "Home", new { page = 1 }, new { id = "link1" })%>

为什么我这样写获得pageValue 是null,而不是我传递的page=1
public ActionResult Test()
{
string pageValue = Request.QueryString["page"];
return View();
}

谢谢!

 回复 引用 查看   
#22楼2011-09-16 16:53 | 中迁仙人      
好东西,收藏了。
 回复 引用 查看   
#23楼2011-11-02 21:24 | 夏侯也      
@传说中的宝玉
改成 new { @readonly="readonly" },readonly是C#的关键字

 回复 引用 查看   
#24楼2011-11-09 10:19 | 唍羙の神      
你好,我想问下,如果我想要的链接是这样用html.actionLink该如何处理啊
<a href='/default'><p>这是一个链接</p></a>