ASP.NET MVC3教程
ASP.NET MVC3 电影示例系列:共九篇 [文章列表]
这里的文章是ASP.NET官网的教程,这里做翻译而已,才疏学浅,翻译错误的地方,请指正,原文地址:Adding a View(C#)
在这个章节中你将会修改HelloWorldController类来使用视图模板文件,让视图将生成到客户端的HTML响应流的处理过程干净的封装起来。
你将会使用在ASP.NET MVC3中介绍过的新Razor 视图引擎来创建一个视图模板。基于Razor的视图模板使用.cshtml的文件后缀,并提供一个用C#生成HTML输出的优雅方式。Razor在写视图模板时使需要的字符数和击键次数减少到最少,使快速,流畅的编码工作方式成为可能。(译注:and enables a fast, fluid coding workflow,这个翻译凌乱了...)
这就从为HelloWorldController类的Index方法是用视图模板开始。当前Index方法在控制器类中以硬编码的方式返回一个字符串信息。按如下的方式修改Index方法,让其返回一个View 对象:
public ActionResult Index()
{
return View();
}
代码使用一个试图模板来生成HTML响应流到浏览器。在项目中,添加一个Index方法使用的视图模板。要添加视图,在Index方法内右键并点击添加视图。
添加视图的对话框将显示,保留默认设置,点击确定按钮:
你可以在解决方案资源管理器中看到,已经生成MvcMovie\Views\HelloWorld文件夹和MvcMovie\Views\HelloWorld\Index.cshtml文件:
下面是创建的Index.cshtml文件:
在<h2>标签下方加些HTML。修改后的MvcMovie\Views\HelloWorld\Index.cshtml文件展示如下:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
运行应用程序,并访问HelloWorld控制器(http://localhost:xxxx/HelloWorld)。在控制器中的Index方法并没有做很多的工作,它仅是简单的运行了return View(),用来指定该方法需要使用视图模板文件来生成到浏览器的响应流。因为你没有明确指定需要使用的视图文件名称,ASP.NET MVC默认使用\Views\HelloWorld文件夹下的Index.cshtml文件。下图显示的是在视图中硬编码的字符串。
看起来不错。然而,注意到浏览器的标题栏中显示的是“Index”,并且页面的大标题显示的是“My MVC Application.”。让我们改掉它。
更改视图和布局页面
首先,你想要修改页面顶部的标题“My MVC Application"。这文本是所有页面通用的。虽然它在程序的每个页面显示,但实际上它仅在项目的唯一一个地方实现。在解决方案资源管理器中路由到/Views/Shared文件夹中,并打开_Layout.cshtml文件。这个文件被称作是布局页,它为其他的所有页面中被当作”壳”来共享使用(译注:这个类似于Web Form中的MasterPage)。
布局模板允许你在一个页面指定含你站点布局的HTML,并在你站点中多个页面使用。注意在文件近底端的@RenderBody()行。RenderBody是一个占位符,所有你创建的所有视图页面,将会被“包裹”进这个布局页面的这个位置。在布局模板里面将标题由“My MVC Application”改为“MVC Movie App"。
<div id="title">
<h1>MVC Movie App</h1>
</div>
运行应用程序,这回它显示的就是”MVC Movie App“了。 点击关于链接,你也将看到页面显示的是”MVC Movie App"。我们可以在layout模板中修改一次就可以让站点的所有页面都得到新的标题。
完整的_Layout.cshtml文件显示如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
</head>
<body>
<div class="page">
<header>
<div id="title">
<h1>MVC Movie App</h1>
</div>
<div id="logindisplay">
@Html.Partial("_LogOnPartial")
</div>
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
</ul>
</nav>
</header>
<section id="main">
@RenderBody()
</section>
<footer>
</footer>
</div>
</body>
</html>
现在,让我们来更改Index页面(View)的标题。
打开mvcMovie\Views\HelloWorld\Index.cshtml。这里需要修改两个地方:首先,显示在浏览器标题栏中的文本,其次是页面的副标题(<h2>元素)。你可以让他们有一点点的不同,因此你可以看出来修改的代码属于程序的那一块。
@{
ViewBag.Title = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
为了指明显示的HTML标题,上面的代码设置了ViewBag对象的Title属性(在Index.cshtml视图模板中的ViewBag)。如果你回顾下前面的布局模板(layout)源代码,你就会发现,在布局模板的HTML的<head>中的<title>元素里使用了这个值(译注:ViewBag.Title)。用这个方法,你可以非常容易的在你的视图模板和布局文件中传递其它参数。
运行应用程序,访问http://localhost:xx/HelloWorld。注意浏览器的标题栏,页面的 主副标题都被修改了。(如果你在浏览器中没有看到改变,你可能看的是缓存内容,在浏览器中按Ctrl + F5来强制刷新来自服务端的响应)(译注:Ctrl+F5是强制使用服务端的最新内容,不再使用本地缓存)。
也请注意Index.cshtml视图模板是如何与_Layout.cshtml试图模板合并作为单个HTML响应流发送到浏览器的。在你的应用程序中布局模板可以非常简单的修改这些并将修改应用到所有的页面中。
不过我们这点点的"数据"(这个例子中是"Hello from our View Template!")是硬编码的。这个MVC应用程序有了一个"V"(View)并且你也有"C"(Controller),但是,还没有"M"(Model)。很快,我们将演示如何创建一个数据库,并从其中获取模型数据。
从控制器传递数据到视图
不过,在我们创建数据库并讨论模型之前,让我们首先来讨论下从控制器传递信息到视图中。控制器类在响应传入URL请求时被调用。控制器类是你编写代码的地方,它需要处理传入的参数,从数据库中获取数据,并最终确定发送回浏览器中的响应类型。而后视图模板在控制类中可被用来生成和格式化到浏览器的HTML响应。
控制器负责为视图模板提供任何生成到浏览器的响应所需的数据或对象。视图永远都不应该处理业务逻辑或直接与数据库交互。相反,它应该仅处理控制器提供的数据。保持“分离关注点”(译注:SoC)能有效的让你的代码更加整洁和更高的可维护。
现在,在HelloWorldController类中的Welcome方法已经获取了name和numTimes参数,并把它们的值直接输出到了浏览器中。让我们修改控制器来使用视图而不是使用控制器生成字符串的响应。视图模板将动态生成响应,这就意味着,为了生成响应你需要从控制器中向视图传递适当的元数据。你可以通过控制器将视图模板需要使用的动态数据赋值给视图模板随后可访问的ViewBag对象中。
回到HelloWorldController.cs文件,修改Welcome方法,为ViewBage对象添加Message和NumTimes值。ViewBag是一个动态对象,这就意味着,你可以赋予任何你想要的数据;在你为ViewBag赋予值之前,ViewBag对象没有已定义的属性。完整的HelloWorldController.cs文件看起来会像这样:
using System.Web;
using System.Web.Mvc;
namespace MvcMovie.Controllers
{
public class HelloWorldController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Welcome(string name, int numTimes = 1)
{
ViewBag.Message = "Hello " + name;
ViewBag.NumTimes = numTimes;
return View();
}
}
}
现在,ViewBag对象包含了数据,并会自动的传递到视图中。
下一步,你需要一个Welcome的视图模板!在调试菜单中,选择生成MvcMovie以确保当前项目被编译。
而后在Welcome的方法内右键,并选择添加视图。添加视图对话框看起来像下图:
点击添加,随后添加<h2>元素后面的代码到新的Welcome.cshtml文件中。你将创建一个根据用户需要的次数显示“Hello”的循环。完整的Welcome.cshtml文件展示如下:
@{
ViewBag.Title = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i=0; i < ViewBag.NumTimes; i++) {
<li>@ViewBag.Message</li>
}
</ul>
运行程序,并访问如下的URL:
http://localhost:xx/HelloWorld/Welcome?name=Scott&numtimes=4
现在,数据将从URL中提取并自动传入控制器。控制器将数据封入ViewBag对象中,并将ViewBag传入视图。而后,视图将以HTML的方式将数据显示给用户。
恩,这就是模型“M"的一种,不过不是数据库的。让我们记住所学并创建电影的数据库(原文:Let's take what we've learned and create a database of movies.)。
翻译有些地方生硬,有些地方只是表达了意思,也有些地方,能看懂,但翻译出来困难。可能有些地方连我也理解错了。希望能给初学者带来一些帮助。