【译】《Pro ASP.NET MVC4 4th Edition》第二章(二)
本文地址http://www.cnblogs.com/outtamyhead/archive/2013/03/21/2973205.html,转载需保留本地址
说在前面:
1、由于是头次翻译整本书籍,所以错误难免,希望大家都提出来,翻译的不好还望大家少拍砖多鼓励。
2、该系列没有按照原文直译,而是加入了我的一些言语在里面(在没有改变原意的情况下),所以大家在看的时候希望有所对照。
3、该系列每周出一或二篇博客,因为我最近很忙,一直在加班,很累的说。
4、该系列不提供原版文字,希望看原版的可以自行下载Pdf。
5、该系列省去了前面的废话,单刀直入,讲主体内容。
第二章:第一个ASP.NET MVC4程序(中)
渲染Web页面
前面的列子并不是从HTML输出的---它只是“Hello World”字符串。要给浏览器请求产生一个HTML响应,我们需要添加一个视图。
添加并渲染视图
首先要做的就是修改我们的Index动作方法,如清单2-3。
清单2-3using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace PartyInvites.Controllers { public class HomeController : Controller { public ViewResult Index() { return View(); } } }
在清单2-3中更改的部分加粗显示了。当我们从Action方法返回一个ViewResult,我们就已经命令MVC去渲染这个视图了。我们通过调用View方法创建了一个无参的ViewResult。这也就告诉MVC为这个动作去渲染默认页。
如果你在这个时候去运行程序,你会发现MVC框架会试图找到一个默认页去使用。如图2-8所示的错误消息。
这个错误信息非常有帮助。它不仅告诉我们MVC不能为我们的动作方法找到合适的视图并且告诉了我们MVC是在哪些地方来找这个视图的。这是另一个关于MVC约定的很好的例证:视图是通过命名约定来与动作方法关联的。我们的动作方法叫做Index,我们的控制器叫做Home,并且我们可以从2-8中知道MVC试图在【Views】文件夹中找到那些叫做Index的文件。
要添加一个视图,那么就停止调试,然后在HomeController.cs代码文件中在动作方法上右键(不论是在方法名上或者在方法体中),然后选择【Add View】,这个菜单将打开【Add View】对话框,如图2-9所示。
取消【Use a layout or master page】选择项。我们在这个例子中不使用布局,我们会在第7章中讲到这些。点击【Add】按钮,Visual Studio会帮我们在【Views】-【Home】文件夹里创建一个新文件,叫做Index.cshtml。如果你反过头去看2-8的错误信息,你会发现这个新文件正是MVC试图查找的那些文件中的一个。
提示:.cshtml扩展名表示是由Razor处理的C#视图。MVC的上一版本是依赖ASPX试图引擎,视图文件的扩展名是.aspx。
Visual Studio自动打开了Index.cshtml文件。你会看见在这里面大部分都是Html,而不一样的地方看起来像这个:
@{ Layout = null; }
这是一个可以被Razor视图引擎解析的表达式。这是一个小巧的例子。它仅仅告诉Razor我们没有选择母版页。我们稍后再提Razor。把清单2-4中加粗的部分添加到Index.cshtml中。
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> Hello World (from the view) </div> </body> </html>
添加的部分用来显示另一条简单的消息。选择【Start Debugging】来启动程序并且来测试一下我们的视图。你会看到与2-10中一些相似的东西。
当我们第一次编辑Index动作方法的时候,它返回了一个字符串。这说明MVC除了向浏览器传递了一个字符串之外没有做任何事情。现在这个Index方法返回了一个ViewResult,我们命令MVC去渲染一个视图并返回HTML。我们没有告诉MVC哪个视图是我们要用的,所以MVC依据命名约定找到了一个自动匹配的。这个约定就是视图具有动作方法的名称并且它位于以控制器命名的文件夹中---~/Views/Home/Index.cshtml。
除了字符串和ViewResult,我们可以从动作方法中返回其他的一些结果。例如,如果我们返回一个RedirectResult,我们就会使浏览器重定向到另外一个URL中。如果我们返回一个HttpUnauthorizedResult,我们将迫使用户去登录。
这些类统称为动作结果,并且它们都是从ActionResult类派生的。动作结果系统能够使我们封装并重用在动作中的常用响应。本书中我们将让你了解它们,并演示一些复杂的应用
添加动态输出
一个Web平台全部的目标就是构建并显示动态输出。在MVC中,这份工作由控制器来担任,它构造数据并传递到视图中,而视图负责渲染到HTML中。
有一种方法可以将数据从控制器传递到视图中,那就是使用ViewBag,ViewBag是Controller基类中的成员。ViewBag是一个动态对象,你可以指定任意属性,让这些值在随后要渲染的视图中可用。在清单2-5中,在HomeController.cs中,用这种方法传递了一些简单的动态数据。
清单2-5using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace PartyInvites.Controllers { public class HomeController : Controller { public ViewResult Index() { int hour = DateTime.Now.Hour; ViewBag.Greeting = hour < 12 ? "Good Morning" : "Good Afternoon"; return View(); } } }
当我们分配一个值给ViewBag.Greeting属性时就给视图提供了数据。ViewBag是动态对象的一个代表,Greeting属性并不存在,直到我们分配一个值---这就允许我们在没有定义类之前以一种自由流畅的方式从控制器传递值到视图中。
我们在视图中再次使用ViewBag.Greeting属性来获取数值,如清单2-6。
清单2-6@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> @ViewBag.Greeting World (from the view) </div> </body> </html>
添加到清单2-6中的是一个Razor表达式,当我们在控制器的Index方法中调用View方法,MVC框架会定位到Index.cshtml视图并要求Razor视图引擎去解析文件中的内容。Razor就会寻找到像我们添加的那个表达式并执行它们。在这个例子中,执行的表达式的含义是向我们分配的ViewBag.Greeting属性插入值。
关于Greeting这个属性名称并没有特别之处;你可以用其他任何一个属性名称来替换它并且它一样会起效,而且我们可以通过分配多个属性来实现从控制器到视图传递多值的想法。我们可以通过运行项目来看一看我们的第一个动态MVC输出,如图2-11.