原文:Adding a view

作者:Rick Anderson

翻译:魏美娟(初见)

校对:赵亮(悲梦)高嵩(Jack)娄宇(Lyrics)许登洋(Seay)姚阿勇(Dr.Yao)

本节将修改 HelloWorldController 类,把使用 Razor 视图模板文件为客户端生成 HTML 响应的过程干净利落地封装起来。

您可以使用 Razor 视图引擎创建一个视图模板。基于 Razor 的视图模板的文件使用 .cshtml 作为其扩展名,并用 C# 优雅地输出 HTML。用 Razor 编写视图模板能减少字符的个数和敲击键盘的次数,并使工作流程快速灵活。

目前,控制器类中的 Index 方法返回的是一串硬编码的字符串。按下面的代码所示,修改 Index 方法使其返回视图对象:

public IActionResult Index()
{
return View();
}

上例中 Index 方法用一个视图模板生成 HTML 响应给浏览器。控制器方法(也称为 action 方法),比如上面的 Index 方法,通常返回 IActionResult (或者派生自 ActionResult 的类),而不是字符串那样的基元类型。

  • 右击 Views (视图)文件夹,选择 Add > New Folder (添加 > 新建文件夹),然后将文件夹命名为 HelloWorld.

  • 右键点击 Views/HelloWorld (视图/Helloworld)文件夹,选择 Add > New Item (添加->新建项)

  • Add New Item - MvcMovie (添加新建项 - MvcMovie)对话框中:

    • 在右上方的搜索框中输入关键词 view

    • 点击 MVC View Page (MVC 视图页)

    • Name (名称)框中, 保持默认的 Index.cshtml

    • 点击 Add (添加)

用以下代码替换 Razor 视图文件 Views/HelloWorld/Index.cshtml :

@{
ViewData["Title"] = "Index";
} <h2>Index</h2> <p>Hello from our View Template!</p>

导航到 http://localhost:xxxx/HelloWorldHelloWorldControllerIndex 方法只干一件事——运行 return View(); 语句来引导控制器方法使用指定的视图模板文件,为浏览器渲染最终的响应结果。 因为没有明确指定所使用视图模板的文件名,MVC 默认使用 /Views/HelloWorld 文件夹中的 Index.cshtml 视图文件。下图显示了在视图中硬编码的字符串 "Hello from our View Template!" 。

如果浏览器窗体比较小(比如在手机设备上),可能需要切换(点击)右上方的 Bootstrap navigation button才能看到 HomeAboutContactRegisterLog in 这些链接。

改变视图和布局页

点击菜单链接(MvcMovieHomeAbout)。每个页面都显示相同的菜单布局。菜单布局在 Views/Shared/_Layout.cshtml 文件中实现。打开 Views/Shared/_Layout.cshtml 文件。

Layout 模板允许你在一处指定网站的 HTML 容器布局,然后在网站下的多个页面中使用。找到 @RenderBody() 那行。 RenderBody 是一个占位符,是你所有指定视图的显示位置,“包裹在”布局页内。例如,点击 About 链接, Views/Home/About.cshtml 视图就会在 RenderBody 方法内渲染。

改变标题元素的内容。在布局模板中将锚(即 A 标签,译者注)文本改成“MVC Movie”,控制器将 Home 改成 Movies ,如下列高亮显示的:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie App</title> <!--手动高亮--> <environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</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="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-controller="Movies" asp-action="Index" class="navbar-brand">Mvc Movie</a> <!--手动高亮-->
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
@await Html.PartialAsync("_LoginPartial")
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>&copy; 2016 - MvcMovie</p>
</footer>
</div> <environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment> @RenderSection("scripts", required: false)
</body>
</html>

警告

我们尚未实现 Movies 控制器,故若你点击该链接,将会得到 404 错误(文件未找到)。

保存,点击 About 链接。注意每个页面怎样显示 Mvc Movie 链接。只在布局模板中改变一次,网站中的所有页面都显示新的链接和新的标题。

查看一下 Views/_ViewStart.cshtml 文件:

@{
Layout = "_Layout";
}

Views/_ViewStart.cshtml 文件将 Views/Shared/_Layout.cshtml 文件引入每个视图中。可以利用 Layout 属性设置不同的布局视图,或者将其设置成 null 这样就不会使用布局视图了。

现在,让我们改变 Index 视图的标题。

打开 Views/HelloWorld/Index.cshtml 。这里有2个地方需要改变:

  • 出现在浏览器上的标题文本
  • 二级标题 (<h2> 元素).

你可以一点点改,这样就可以看到哪些代码改变了应用程序的哪些地方。

@{
ViewData["Title"] = "Movie List"; //手动高亮
} <h2>My Movie List</h2> <!--手动高亮--> <p>Hello from our View Template!</p>

在以上代码中 ViewData["Title"] = "Movie List";ViewDataDictionary 的 Title 属性设置为 "Movie List"。Title 属性被用在布局页的 <title> Html元素中:

<title>@ViewData["Title"] - Movie App</title>

保存并刷新页面。注意浏览器标题、主标题和副标题都变化了(如果你没看到变化,可能因为缓存的缘故,在浏览器中按下 Ctrl+F5 强制刷新)。浏览器标题由我们设置在 Index.cshtml 视图模板中的 ViewData["Title"] 以及位于布局页的 "- Movie App" 组合构成。

同时注意,Index.cshtml 视图模板的内容是怎样和 Views/Shared/_Layout.cshtml 视图模板合并的,和一个HTML响应是怎样被发送到浏览器的。布局模板非常易于进行作用于应用程序中所有页面的修改。了解更多请参考 : Layout

不过,我们的这点“数据”(本例中的消息 "Hello from our View Template!")还是硬编码的。MVC 应用程序里已经有了个“V”(View),我们也已经创建了一个“C”(Controller),但现在还没有“M”(Model)。接下来我们将快速展示如何创建数据库并从中搜索模型数据。

从控制器传递数据到视图

在谈到数据库和模型之前,让我们先讨论从控制器传递信息到视图。控制器类在响应传入的 URL 请求时被调用。控制器类是编写代码处理传入的浏览器请求,从数据库中检索数据,并最终决定发送什么类型的响应返回给浏览器的地方。然后可以在控制器中使用视图模板生成和格式化 HTML 来响应给浏览器。

控制器负责提供所需要的任何数据或者对象,以便视图模板向浏览器呈现响应。最佳实践:视图模板不应该执行业务逻辑或者直接与数据库进行交互,而应该只使用控制器提供给它的数据。保持这种 “关注点分离” 有助于保持你的代码整洁,可测试以及更易于维护。

目前,HelloWorldController 类中的 Welcome 方法接受一个 name 和一个 ID 参数,然后直接将值输出到浏览器。让我们更改控制器来使用视图模板,而不是让控制器使用字符串呈现这个响应。视图模板将生成一个动态响应,这就意味着需要通过控制器传递恰当的数据给视图以生成响应。要做到这一点,可以让控制器将视图模板所需的动态数据(参数)放在视图模版随后可以访问的 ViewData 字典中。

回到 HelloWorldController.cs 文件,在 Welcome 方法中添加一个 MessageNumTimes 的值到 ViewData 字典中。 ViewData 字典是个动态对象,这意味着可以把任何你想要的数据添加进去。在你往里面添加东西之前,ViewData 对象没有已定义的属性。MVC 模型绑定系统自动映射地址栏中查询字符串的命名参数(namenumTimes)到你的方法参数中。完整的 HelloWorldController.cs 文件看起来是这样的:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web; namespace MvcMovie.Controllers
{
public class HelloWorldController : Controller
{
public IActionResult Index()
{
return View();
} public IActionResult Welcome(string name, int numTimes = 1)
{
ViewData["Message"] = "Hello " + name;
ViewData["NumTimes"] = numTimes; return View();
}
}
}

ViewData 字典对象包含将要传递给视图的数据。下一步,需要一个 Welcome 的视图模板。

  • 右键点击 Views/HelloWorld 文件夹,点击 Add > New Item (添加 > 新建项)。

  • Add New Item - MvcMovie (添加新项 - MvcMovie)对话框中

    • 在右上角的搜索框中输入关键词 view

    • 点击 MVC View Page (MVC 视图页)

    • Name (名称)框中,输入 Welcome.cshtml

    • 点击 Add (添加)

Welcome.cshtml 视图模板中创建一个循环来显示 "Hello" NumTimes。用以下代码完全替换 Views/HelloWorld/Welcome.cshtml 中的内容:

@{
ViewData["Title"] = "About";
} <h2>Welcome</h2> <ul>
@for (int i = 0; i < (int)ViewData["NumTimes"]; i++)
{
<li>@ViewData["Message"]</li>
}
</ul>

保存修改并打开浏览器,访问这个地址:

http://localhost:xxxx/HelloWorld/Welcome?name=Rick&numtimes=4

数据从 URL 中获取并用模型绑定器将数据传递给控制器。控制器将数据封装到 ViewData 字典中,并将对象传递到视图里。然后,视图将数据以 HTML 的形式渲染到浏览器中。

在上面的例子中,我们用 ViewData 字典将数据从控制器传递到视图中。在后面的教程中,我们将使用视图模型(View Model)将数据从控制器传递到视图中。用视图模型传递数据的方法通常比 ViewData 字典的方式更受欢迎。查看 Dynamic V Strongly Typed Views 了解更多信息。

好吧,这也算是一种 Model 中的“M”吧,但无论如何都不是数据库模型。让我们用学到的东西创建一个电影数据库吧。

返回目录

ASP.NET Core 中文文档 第二章 指南(4.3)添加 View的更多相关文章

  1. ASP.NET Core 中文文档 第二章 指南(4.6)Controller 方法与视图

    原文:Controller methods and views 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘) .张仁建(第二年.夏) .许登洋(Seay) .姚阿勇 ...

  2. ASP.NET Core 中文文档 第二章 指南(4.4)添加 Model

    原文:Adding a model 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:许登洋(Seay).孟帅洋(书缘).姚阿勇(Mr.Yao).夏申斌 在这一节里,你将添加一些类来 ...

  3. ASP.NET Core 中文文档 第二章 指南 (09) 使用 Swagger 生成 ASP.NET Web API 在线帮助测试文档

    原文:ASP.NET Web API Help Pages using Swagger 作者:Shayne Boyer 翻译:谢炀(kiler) 翻译:许登洋(Seay) 对于开发人员来说,构建一个消 ...

  4. ASP.NET Core 中文文档 第二章 指南(1)用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序

    原文:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 作者:Daniel Roth.Steve Smith ...

  5. ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

    原文:Building Your First Web API with ASP.NET Core MVC and Visual Studio 作者:Mike Wasson 和 Rick Anderso ...

  6. ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序

    原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...

  7. ASP.NET Core 中文文档 第二章 指南(4.1)ASP.NET Core MVC 与 Visual Studio 入门

    原文:Getting started with ASP.NET Core MVC and Visual Studio 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:刘怡(Alex ...

  8. ASP.NET Core 中文文档 第二章 指南(4.5)使用 SQL Server LocalDB

    原文:Working with SQL Server LocalDB 作者:Rick Anderson 翻译: 魏美娟(初见) 校对: 孟帅洋(书缘).张硕(Apple).许登洋(Seay) Appl ...

  9. ASP.NET Core 中文文档 第二章 指南(5) 在 Nano Server 上运行ASP.NET Core

    原文 ASP.NET Core on Nano Server 作者 Sourabh Shirhatti 翻译 娄宇(Lyrics) 校对 刘怡(AlexLEWIS).许登洋(Seay).谢炀(kile ...

  10. ASP.NET Core 中文文档 第二章 指南(8) 使用 dotnet watch 开发 ASP.NET Core 应用程序

    原文:Developing ASP.NET Core applications using dotnet watch 作者:Victor Hurdugaci 翻译:谢炀(Kiler) 校对:刘怡(Al ...

随机推荐

  1. app开发外包注意事项,2017最新资讯

    我们见过很多创业者,栽在这app外包上.很多创业者对于app外包这件事情不是特别重视,以为将事情交给app外包公司就完事了,实际上不是的.无论是从选择app外包公司还是签订合同.售后维护等各方面都有许 ...

  2. ajax异步请求

    做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school.c ...

  3. Js 原型和原型链

    Js中通过原型和原型链实现了继承 Js对象属性的访问,首先会查找自身是否拥有这个属性 如果查到,则返回属性值,如果找不到,就会遍历原型链,一层一层的查找,如果找到就会返回属性值 直到遍历完Object ...

  4. Partition:分区切换(Switch)

    在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...

  5. dubbo服务提供与消费

    一.前言 项目中用到了Dubbo,临时抱大腿,学习了dubbo的简单实用方法.现在就来总结一下dubbo如何提供服务,如何消费服务,并做了一个简单的demo作为参考. 二.Dubbo是什么 Dubbo ...

  6. Asp.net Core准备工作

    1.安装环境 安装.Net Core SDK 安装VS2015 Update3 安装DotNetCore.1.0.1-VS2015Tools.Preview2.0.2.exe 2.新建Core工程 项 ...

  7. javaScript生成二维码(支持中文,生成logo)

    资料搜索 选择star最多的两个 第一个就是用的比较多的jquery.qrcode.js(但不支持中文,不能带logo)啦,第二个支持ie6+,支持中文,根据第二个源代码,使得,jquery.qrco ...

  8. 免费公开课,讲解强大的文档集成组件Aspose,现在可报名

    课程①:Aspose.Total公开课内容:讲解全能型文档管理工具Aspose.Total主要功能及应用领域时间:2016-11-24 14:30 (暂定)报名地址:http://training.e ...

  9. git init和git init -bare区别

    1 Git init  和 git init –bare 的区别 用"git init"初始化的版本库用户也可以在该目录下执行所有git方面的操作.但别的用户在将更新push上来的 ...

  10. NV显卡Ubuntu14.04更新软件导致登录死循环,不过可以进入tty模式

    注意:此方法只适用于nv显卡的电脑! 在网上寻找各种方法无果的情况下,选择重新安装显卡驱动,成功登录进入图形界面. 一.首先需要在另外一台电脑(windows系统也可以)上下载NVIDIA相应显卡驱动 ...