Intro to ASP.NET MVC 4 with Visual Studio [译四:添加一个视图]
作者:Rick Anderson and Scott Hanselman
译者:PeterZhang
原文: http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
注: 边读编译,如有不准确之处,请予以纠正,谢谢!!!
-----------------------------------------------------------------------------------------------------------------
本节将修改 HelloWorldController 类,使用视图模板来封装生成 HMLT响应客户的过程。
使用 ASP.NET MVC 3 引入的 Razor 视图引擎创建一个视图模板文件。基于 Razor 的视图模板是扩展名为.cshtml的文件,通过使用C#提供简洁的方式创建 HTML 输出。Razor 减少了编辑视图模板时的代码量,能够快速、流畅的编程。
现在控制器类中 Index 方法硬编码返回一个字符串消息。修改 Index 方法返回一个 View 对象,如下面代码所示:
public ActionResult Index() { return View(); }
上面的 Index 方法使用视图模板生成 HTML 响应给浏览器。控制器方法(也就是action方法),例如上面的 Index 方法,通常返回一个ActionResult(或者ActionResult的派生类),而不是像字符串这样简单的类型。
在项目中,添加一个可以使用 Index 方法的视图模板。为完成添加视图,在 Index 方法中右键选择“Add View”。
在“Add View”弹出框出现后,保留默认,然后点击“Add”按钮。
文件夹MvcMovie\Views\HelloWorld folder 和文件 MvcMovie\Views\HelloWorld\Index.cshtml 被创建,你可以项目浏览器中看到它们。
下面的截图显示了刚刚创建的 Index.cshtml 文件:
在<h2>标签下添加如下HTML。
<p>Hello from our View Template!</p>
完整的 MvcMovie\Views\HelloWorld\Index.cshtml 文件显示如下。
@{ ViewBag.Title = "Index"; } <h2>Index</h2> <p>Hello from our View Template!</p>
注意:如果你正在使用 IE9 且没有没有看到上面黄色高亮的<p>Hello from our View Template!</p>,点击IE中的兼容视图按钮,使略图变成。也可以在 FireFox 或 Chrome 中看本教程的程序。
如果你在使用 Visual Studio 2012,在项目浏览器中,右键 index.cshtml 文件,然后选择“View in Page Inspector”。
Page Inspector 教程 有更多关于这个新工具的信息。
另一种方式,运行程序且浏览至 HelloWorld 控制器(http://localhost:xxxx/HelloWorld)。控制器中的 Index 方法没有做太多工作,只是简单的执行 return View() 语句,表明该方法使用视图模板文件来生成响应返回给浏览器。因为没有明确指定要使用的视图模板文件的名字,所以 ASP.NET MVC 默认使用 \View\HelloWorld 文件夹下的 index.cshtml 视图文件。下图显示了在视图中硬编码的字符串 “Hello from our View Templated!”。
看起来不错。然而,注意浏览器的标题栏显示"Index My ASP.NET A“,在页面上部是一个”your logo here."的大链接。在“your logo here.”链接下面是注册和登陆的链接,再下面就是 Home, About 和 Contact 页面的链接。让我们来更改这些内容。
更改视图和布局页面
首先,更改页面上部的“your logo here.”标题。这个文本在所有页面上是相同的。尽管在项目中每个页面都有这个文本,但是只在项目的一个地方实现。在项目浏览器中找到/Views/Shared文件夹,打开_Layout.cshtml文件。这个文件被称为布局文件,是所有页面共享的"壳“。
布局模板使能在一个地方指定网站HTML容器布局,然后应用于网站的多个页面。找到 @RenderBody() 行。RenderBody是一个占位符,所有创建的特定视图都显示,封装在布局页面中。例如,你选择了About链接,在 RenderBody方法中呈现 View\Home\About.cshtml 视图。
在布局文件中把网站标题从“your logo here”改成“MVC Movie”。
<div class="float-left"> <p class="site-title">@Html.ActionLink("MVC Movie", "Index", "Home")</p> </div>
用下面的标签替换标题元素内容:
<title>@ViewBag.Title - Movie App</title>
运行程序可以看到标题现在是“MVC Movie”。点击About链接,可以看到这个页面也显示“MVC Movie”。我们能够只更改布局文件一次,就能在所有页面显示新标题。
现在,更改Index视图的标题。
打开MvcMovie\View\HelloWorld\Index.cshtml。这有两个地方要做修改:首先,浏览器标题的文本,然后是第二个header(<h2>元素)。 对它们做微小改变,以便可以看出哪些代码改变影响程序的哪部分。
@{ ViewBag.Title = "Movie List"; } <h2>My Movie List</h2> <p>Hello from our View Template!</p>
为了表明显示HTML标题,上面的代码设置ViewBag对象的Title属性(在index.cshtml视图模板里)。回头看下布局文件的源代码,会注意到模板在使用我们之前修改的HTML<head>部分中的<title>元素中的值。使用ViewBag这种方式,可以容易地在视图模板和布局文件之间传递参数。
运行程序,然后浏览至http://localhost:xx/HelloWorld。注意浏览器的标题,主标题和副标题已经改变了。(如果你在浏览器中没有看到变化,你可能在浏览缓存中的内容。在浏览器中按Ctrl + F5,强制加载服务器响应。)浏览器中的标题是index.cshtml中设置的ViewBag.Title和布局文件中添加的“-Movie App”。
注意Index.cshtml视图模板内容如何和_Layout.chtml视图模板合并,然后HTML响应被发送回浏览器。布局模板使修改很容易地应用于程序所有页面。
这些修改的“数据”(这个例子中的“Hello from our View Template!”消息)是硬编码的。这个MVC程序有“V”(视图)并且已经有个“C”(控制器),但是还没有“M”(模型)。不久,我们将演示如何创建数据库并从中得到模型数据。
将数据从控制器传递到视图
在我们转到数据库和谈论模型前,让我们先谈论下从控制器传递数据到视图。 控制器类在相应URL请求时被调用。控制器类里写代码处理浏览器请求,从数据库中检索数据,最终确定发送给浏览器响应的类型。从控制器中获得视图模板用来生成和格式化HTML响应给浏览器。
控制器负责提供视图模板中需要的任何数据或对象以生成响应给浏览器。最佳做法:视图模板永远不要执行业务逻辑或直接和数据库交互。相反,视图模板只处理控制器提供的数据。保持这种”separatin of concerns“帮助保持你代码的简洁、可测试和易维护。
目前,HelloWorldController类中的Welcome action方法接受name和numTimes参数,然后直接将值输出到浏览器。 与其控制器直接生成字符串响应,倒不如让我们更新控制器使用视图模板。视图模板将生成动态响应,意味着你需要从控制器传递数据到视图以生成响应。可以通过将视图模板需要的数据存储在ViewBag对象中,然后视图模板可以获得。
返回到HelloWorldController.cs文件并更新Welcome方法,添加Message和NumTimes值到ViewBag对象中。ViewBag是一个动态对象,意味着你可以把任何想放的值存储在它中;ViewBag没有已定义的属性,直到你存值到里面。ASP.NET MVC模型绑定系统自动映射地址栏查询字符串中的命名参数(name和numTimes)到方法的参数。完整的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视图模板!在 Build菜单,选择生成 MvcMovie 以确保项目编译通过。
然后在Welcome方法中右键选择"Add View“。
”Add View“对话框显示如下:
点击”Add“,然后在新的Welcome.cshtml文件中的<h2>标签下添加如下代码。将创建一个说多次"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:x/HelloWorld/Welcome?name=Scott&numtimes=4
现在通过模型绑定系统从URL获得数据并传递给控制器。控制器将数据封装到ViewBag对象中,然后将对象传递给视图。视图以HTML形式显示数据给用户。
在上面的示例中,我们使用ViewBag对象将数据从控制器传递到视图。在接下来的教程中,我们将使用一个视图模型将数据从控制器传递到视图。使用视图模型传递数据优于使用ViewBag。详细信息请参考Dynamic V Strongly Typed Views。
这是一种”M“的模型,不是数据库那种。让我们根据所学的知识来创建一个movies的数据库。