本人是MVC新手,将从微软官网学习MVC并将看过的英文文档翻译成中文,由于本人英文水平不好,有翻译不准确、错误的地方万望指出,我看到后将会在第一时间修改。另外也希望这一系列文章能为后来者起到引导作用。 微软原文地址:http://www.asp.net/mvc/overview/getting-started/introduction/adding-a-view
添加视图
在本章节中、我将带领你们修改HelloWorldController类。使用视图模板文件简单便捷的封装生成HTML响应的过程。
你将使用Razor View Engine 创建一个视图模板文件。基于Razor的视图模板包含一个以.cshtml为后缀的文件,并且使用C#以一种优雅的方式穿件HTML显示页面。Razor在你创建一个视图模板时可以使你的编码量最小,实现快速流畅的编码工作流。
当前你控制器中的Index方法返回一个硬编码字符串作为消息。修改Index方法,返回一个View对象,具体代码如下:
public ActionResult Index() { return View(); }
|
上面的Index方法通过返回一个View模板来生成一个HTML响应给浏览器。如上面的Index方法的控制器方法(或者Action方法)通常返回一个ActionResult(或一个继承自ActionResult的类)而不是如string一般的原始类型。
右键View\HelloWorld文件夹,点击Add、点击MVC 5 View Page with(Layout Razor)。
在Spacify Name for Item弹出框中输入index然后点击Ok
在Select a Layout Page弹出框中,选择默认的_Layout.cshtml并点击OK
上面显示的弹出框中,左侧边栏中自动勾选上Views\Shared文件。如果你有自定义的布局文件,你也可以选择使用。稍后我将会讲解布局文件。
经过上面的步骤,MvcMovie\Views\HelloWorld\Index.cshtml文件已经创建成功。
用下面代码覆盖已有代码
@{ Layout = "~/Views/Shared/_Layout.cshtml"; } @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p>Hello from our View Template!</p>
|
右键Index.cshtml文件,并选择在浏览器中查看,或者选择在Page Inspector中查看
此外,运行应用程序并进入HelloWorld控制器(http://localhost:xxxx/HelloWorld)。控制器中的Index函数只是简单的返回View(),这个方法只是使用一个视图模板文件展示给浏览器。因为你没有指定展示哪一个视图模板文件,所以ASP.NET MVC默认使用你View\HelloWorld文件夹下的index.cshtml文件。下面的图片显示index.cshtml文件中的硬编码字符串“Hello from our View Template!”
看起来很好。然而,注意看的话,可以发现在浏览器的标题栏显示着"Index My ASP.NET Appli".在页面的顶部也显示的"Application name."
修改视图和布局页
首先你要修改页面顶部的"Application name"链接。这个文本是所有页面共有的。实际上,文本内容在整个项目中只实现在一个地方即使他在每个页面都显示。打开/Views/Shared文件夹下的_Layout.cshtml文件。这种文件叫做布局页,并且它是在共享文件夹中供所有页面使用。
布局模板允许你在网站的某一个地方指定网站的HTML容器布局,然后将它应用在网站的更多页面上。找到@RenderBody()这一行。RenderBody是你创建的视图页面显示的一个占位符。例如你选择了About链接,Views\Home\About.cshtml视图将会呈现在RenderBody函数中
修改Title元素的内容。将ActionLink中的字符串“Application name”修改为“MVC Movie”,并将代表控制器的参数修改为Movies,下面为视图模板的全部内容:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - Movie App</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("MVC Movie", "Index", "Movies", null, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("Home", "Index", "Home")</li> <li>@Html.ActionLink("About", "About", "Home")</li> <li>@Html.ActionLink("Contact", "Contact", "Home")</li> </ul> @Html.Partial("_LoginPartial") </div> </div> </div> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>© @DateTime.Now.Year - My ASP.NET Application</p> </footer> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>
|
运行应用程序,可以明显的看到改变后的“MVC Movie”。点击About链接,你明显可以看到页面显示MVC Movies。我们只需要在布局模板中修改一次,网站中所有页面都会显示更新后的内容。
在我们创建Views\HelloWorld\Index.cshtml 文件的时候,文件里自动包含了下面的代码:
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }
|
上面的Razor代码用来设置布局页。查看Views\_ViewStart.cshtml 文件,发现它也包含类似的Razor代码。
Views\_ViewStart.cshtml 文件定义了所有文件都会使用的常用布局,因此你可以屏蔽或者移除Views\HelloWorld\Index.cshtml中的代码。
@*@{ Layout = "~/Views/Shared/_Layout.cshtml"; }*@ @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p>Hello from our View Template!</p>
|
你可以使用Layout属性来设置不同的布局视图,或者设置null。
现在我们来修改Index视图的标题
打开MvcMovie\Views\HelloWorld\Index.cshtml。这里需要修改两处代码:首先修改浏览器标题,然后修改<h2>标签中的元素。
@{ ViewBag.Title = "Movie List"; } <h2>My Movie List</h2> <p>Hello from our View Template!</p>
|
为了让HTML的Title显示更改,上面的代码为ViewBag对象(index.cshtml视图模板中)的Title属性赋值。需要注意的是布局模板(Views\Shared\_Layout.cshtml)在<title>标签中使用了上边的ViewBag.Title变量
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - Movie App</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head>
|
通过ViewBag你可以轻松的在你的视图模板和布局文件中传递其他参数。
运行应用,可以看见浏览器标题、主标题和二级标题已经改变了。(如果你没有看见变化,那么显示的可能是缓存过的界面。在浏览器中按Ctrl+F5即可)。我们在Index.cshtml视图模板中通过ViewBag.Title设置的的标题在浏览器中显示成功。
需要注意的是,这里的Index.cshtml视图模板时图和与_Layout.cshtml视图模板合并,并生成一个HTML响应发送到浏览器的。布局模板使你应用程序中改变所有界面变得简单。
本文中我们的数据都是使用硬编码(如:“Hello from our View Template!”)。我们已经介绍了MVC中的V(View)和C(Controller),但是还没有M(Model)。不久,我们将介绍如何创建一个数据库和检索模型数据。
从Controller到View传递数据
在我们使用数据库讲解Model前,让我们先讲解下从控制器到视图传递值。控制器类被用来响应传入的URL响应。控制器类是你编写的代码处理传入的浏览器请求,从数据库中检索数据,并最终决定什么类型的响应发送回浏览器。视图模板可以用于从一个控制器来产生和格式化HTML响应到浏览器。控制器负责提供视图模板将呈现到浏览器所需要的任何数据或对象。一个最佳的实践方法即:一个视图模板不应该执行业务逻辑或直接与数据库交互。反而言之,视图模板则仅仅用来操作控制器提供的数据。这就是所谓的“关注点分离”,这使得代码保持干净,可测试,切易于维护。
目前HellowWorldController类中的Welcome方法需要name和numTImes两个参数,然后返回到浏览器中。而不是控制器呈现这个响应到字符串,汤我们使用一个视图模板来改变控制器。视图模板将会使用你从控制器传递的到视图的参数俩生成一个动态响应。你可以通过控制器使用ViewBag动态传递参数。
让我们打开HelloWorld文件,修改Welcom函数,添加一个NumTImes变量到ViewBag。ViewBag是动态对象,你可以将任何你想放入的变量放到ViewBag中。在你没有放入任何变量前ViewBag没有任何属性。ASP.Net模型绑定系统动态从url中的查询字符串中映射变量到你函数的参数中。所有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包含了将动态传递到View中的数据。下面,你需要一个Welcome视图模板文件。先生成一遍应用程序,然后右键Views\HelloWorld文件。点击Add然后点击MVC 5 View Page with (Layout Razor).
在Specify Name for Item弹出框中输入Welcome然后点击OK。在Select a Layout Page 弹出框中选择_Layout.cshtml然后点击OK。
MvcMovie\Views\HelloWorld\Welcome.cshtml文件创建成功。
使用下面的代码替换Welcome.cshtml文件内容,代码将会循环打印你输入的次数个“Hello”。
@{ 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中。
上面的例子中我们使用ViewBag对象从控制器传递数据到视图中。在下一篇文章中,我们将会使用视图模型从控制器传递数据到视图中。