转自http://firechun.blog.163.com/blog/static/31804522201102711480936/
添加视图模板
要使用视图模板,可以修改HomeController的Index方法,让它返回ActionResult,就象下面这样返回View():
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}
上述修改标志着返回的字符串被替代,我们使用“View”产生返回结果。
现在为我们的项目添加一个适当的视图,把光标定位到Index动作方法上,单击右键,选择“添加视图”,进入
“添 加视图”对话框允许我们方便快捷地产生视图模板文件。默认情况下,“添加视图”对话框会预先填写视图模板的名称以匹配使用它的动作方法,因为我们在 HomeController的Index动作方法上使用右键菜单上的“添加视图”,因此“添加视图”对话框默认填写Index作为视图名称,我们不需要 改变任何选项,点击“添加”按纽。
点击“添加”按纽后,VS在Views\Home目录中创建了一个新的模板:Index.cshtml,如果目录不存在,VS会自动创建它。
“Index.cshtm”的文件名和文件夹非常重要,遵循了ASP.NET MVC约定。\Views\Home匹配HomeController控制器,视图模板名称——Index则匹配显示该视图的控制器动作方法。
使用ASP.NET MVC命名约定返回视图,可以让我们避免显示指定视图模板的名称和位置。当我们在HomeController中编写如下代码时,默认情况下将呈现\Views\Home\Index.cshtml视图模板。
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}
在“添加视图”对话框中按下“添加”按纽后,VS创建并打开Index.cshtml视图模板,Index.cshtml的内容如下所示:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
视 图使用了Razor,一种比ASP.NET及较早版本的ASP.NET MVC使用的Web Forms引擎更简洁的语法。ASP.NET MVC 3仍然支持Web Forms视图引擎,但大多数开发人员认为Razor视图引擎比它更适合ASP.NET MVC 的开发。
首三行用ViewBag.Title设置页面标题,我们很快会看到它是如何工作的更多细节,但现在先让我们更改视图页面的文本,把<h2>标签中的内容改成如下所示:
<h2>This is the Home Page</h2>
运行程序,在主页中我们可以看到新的文本:
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("/Content/Site.css")"
rel="stylesheet" type="text/css" />
<script src="@Url.Content("/Scripts/jquery-1.4.4.min.js")"
type="text/javascript"></script>
</head>
<body>
@RenderBody()
</body>
</html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("/Content/Site.css")"
rel="stylesheet" type="text/css" />
<script src="@Url.Content("/Scripts/jquery-1.4.4.min.js")"
type="text/javascript"></script>
</head>
<body>
<div id="header">
<h1>
ASP.NET MVC MUSIC STORE</h1>
<ul id="navlist">
<li class="first"><a href="/" id="current">Home</a></li>
<li><a href="/Store/">Store</a></li>
</ul>
</div>
@RenderBody()
</body>
</html>
- 因为视图模板遵循标准命名约定,HomeController的Index动作方法通过调用“return View()”找到并且显示\Views\Home\Index.aspx视图模板。
- 通过在\Views\Home\Index.aspx中的定义,主页显示了一条简单的欢迎信息。
- 使用母版页,欢迎信息呈现出标准的HTML布局。
使用模型(Model)把信息传递给视图
视图模板仅仅显示硬编码的HTML内容不足以构建一个令人感兴趣的网站,要创建动态网站,我们应该从控制器动作中传递信息到视图模板。
在Model-View-Controller(模型-视图-控制器)模式中,模型是对应用程序要呈现的数据的对象引用,通常来说,模型对象相当于数据库中的表,但这里不是。
返回ActionResult的控制器动作方法可以把模型对象传递给视图,这使得控制器干净地封装了所有需要的信息生成一个响应,把这些信息传递给视图模板并生成适当的HTML响应。在控制器动作中看它是最容易理解的,那么让我们开始吧。
首先,我们创建一些模型类来描述音乐仓库的类别和唱片,让我们从创建Genre类开始。在你的项目中,右键单击“Models”文件夹,选择“添加->类”,并将文件命名为Genre.cs
在创建的类中增加一个公用的字符串属性——Name
{
public string Name { get; set; }
}
注意:这里你可能会感到奇怪, { get; set; } 是C#自动属性(C#3.0支持)这让我们方便定义属性而不需要声明字段。
下面,按相同的步骤添加唱片类(Album.cs),它有两个属性:Title和Genre
public class Album
{
public string Title { get; set; }
public Genre Genre { get; set; }
}
现在,我们可以修改StoreController,使用视图显示模型信息:
我 们修改StoreController中的Details动作,让它显示单个唱片的信息。在StoreController类的顶部增加using语句以 包含MvcMusicStore.Models命名空间,这样,我们每次使用Album类时,不需要输入 MvcMusicStore.Models.Album ,using部分看起来如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcMusicStore.Models;
下面,我们修改Details控制器动作,让它返回ActionResult而不是字符串,我们曾经对HomeController的Index方法做过同样的修改。
public ActionResult Details(int id)
现在我们修改业务逻辑为视图返回一个Album对象,在本教程的最后,我们会从数据库接收数据,但现在,让我们先从“模拟数据”开始吧。
public ActionResult Details(int id)
{
var album = new Album { Title = "Album " + id };
return View(album);
}
(对var类型变量的解释,不写了)
现在可以创建使用Album生成HTML响应的视图模板,在此之前我们需要生成项目以便让“添加视图”对话框知道我们新建的Album类,在“生成”菜单中选择“生成MvcMusicStore”。
设 置好支持的类后,我们准备创建视图模板,在Details方法上单击右键并在快捷菜单上选择“添加视图”,就象之前为HomeController创建视 图模板一样,由于我们从StoreController中创建,默认会产生 文件\Views\Store\Details.aspx。
和之前不同的是,这次我们把“创建强类型视图”勾选上,然后在“视图数据类”下拉框中选择Album类,“添加视图”对话框将产生视图模板,并将Album对象传递给它。
(以下和原文不同,微软更新太快,原文已经使用MVC 3,因为时间关系,目前我还不打算在我们的项目中使用MVC 3 的Razor语法,因此下面全部使用MVC 2完成,功能和原文保持一致)
Details.aspx的页面指令中包含以下代码:
Inherits="System.Web.Mvc.ViewPage<MvcMusicStore.Models.Album>"
表示这是个Album的强类型视图,可以让我们更容易访问模型的属性,并受VS的“智能感应器”的支持。
在<h2>标签中显示Album的Title属性:
<h2>Album:<%:Model.Title %></h2>
注意当我们输入<%:之后,VS的智能感应器会显示,Model是默认的Album对象名称,并且可以在智能感应器中看到相关的属性和方法。
(注:<%: %>是ASP.NET 4的新语法,等效于<%=Server.HtmlEncode()%>)
运行应用程序并访问URL /Store/Details/5,我们看到了唱片的详细信息:
现在我们同样更新StoreController的Browse动作方法,修改方法的返回值为ActionResult,修改方法的业务逻辑返回一个Gener对象给视图。
public ActionResult Browse(string genre)
{
var genreModel = new Genre { Name = genre };
return View(genreModel);
}
在Browse方法上单击右键选择“添加视图”,添加一个Genre的强类型视图。
更新视图代码:
<h2>Browsing Genre:<%:Model.Name %></h2>
运行应用程序并访问URL /Store/Browse?Genre=Disco,我们看到如下的浏览页面:
最后,让我们做一个稍微复杂点的修改:让StoreController的Index动作方法和视图显示仓库中所有类别的列表,我们使用Genre的集合而不是单个Genre对象。
public ActionResult Index()
{
var genres = new List<Genre>
{
new Genre { Name = "Disco"},
new Genre { Name = "Jazz"},
new Genre { Name = "Rock"}
};
return View(genres);
}
在Index方法上单击右键选择“添加视图”,类型选择Genre,视图内容选择“List”:
Browse Genres</h3>
<p>
Select from <%:Model.Count()%> genres:</p>
<ul>
<%foreach (var genre in Model){%>
<li>
<%:genre.Name%></li>
<%} %>
</ul>
<li>
<a href="/Store/Browse?genre=<%:genre.Name%>"><%:genre.Name%></a></li>
<%} %>
运行没问题,不过使用硬编码可能会为我们带来麻烦,例如,如果我们想重命名控制器,我们必须搜索代码中所有链接到该控制器的地方并进行修改。
注意:在上面的例子中,因为是从当前视图链接到同一个控制器的另一个动作,所以不需要指定控制器的名称。
链接到Browse页面需要传递一个参数,这里我们用Html.ActionLink()有三个参数的重载:
- 1.链接的文本——使用类型名称(genre.Name)
- 2.控制器动作名称——Browse
- 3.路由参数——需要指定参数名称和值,参数名称是genre,值是genre.Name
新的代码:
<%foreach (var genre in Model){%>
<li>
<%:Html.ActionLink(genre.Name,"Browse",new {genre=genre.Name}) %>
</li>
<%} %>
现在运行我们的项目并访问 /Store/ URL,我们可以看到类别列表,每个类别都是一个超链接,点击后会把我们带到/Store/Browse?genre=[genre] URL。
网页产生的HTML代码看起来如下所示:
<ul>
<li><a href="/Store/Browse?genre=Rock">Rock</a>
</li>
<li><a href="/Store/Browse?genre=Jazz">Jazz</a>
</li>
<li><a href="/Store/Browse?genre=Country">Country</a>
</li>
<li><a href="/Store/Browse?genre=Pop">Pop</a> </li>
<li><a href="/Store/Browse?genre=Disco">Disco</a>
</li>
</ul>
(本人注:关于Html.ActionLink()的用途和好处,可以参看我的另一篇文章:布署ASP.Net MVC应用程序时的链接地址问题)