原文: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. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  2. 比Mysqli操作数据库更简便的方式 。PDO

    下面来说一下PDO 先画一张图来了解一下 mysqli是针对mysql这个数据库扩展的一个类 PDO是为了能访问更多数据库 如果出现程序需要访问其他数据库的话就可以用PDO来做 PDO数据访问抽象层1 ...

  3. 使用蓝灯后,IE浏览器以及内置IE浏览器的程序不能使用的解决方案

    使用完蓝灯后,每次使用IE浏览器都不能正常使用,于是有了下面的这个方案 1.通过Win+R 打开注册表编辑器(regedit) 进入目录 HKEY_CURRENT_USER \ Software \ ...

  4. javascript运动系列第一篇——匀速运动

    × 目录 [1]简单运动 [2]定时器管理 [3]分享到效果[4]移入移出[5]运动函数[6]透明度[7]多值[8]多物体[9]回调[10]函数完善[11]最终函数 前面的话 除了拖拽以外,运动也是j ...

  5. dotNet Core开发环境搭建及简要说明

    一.安装 .NET Core SDK 在 Windows 上使用 .NET Core 的最佳途径:使用Visual Studio. 免费下载地址: Visual Studio Community 20 ...

  6. Linux-Rhel6 恢复误删文件

    需要工具extundelete(可通过xshell上传下载到linux)知识点:ifconifig eth0             查看ipfdisk /dev/sda          管理磁盘m ...

  7. [Django]用户权限学习系列之User权限基本操作指令

    针对Django 后台自带的用户管理系统,虽说感觉还可以,但是为了方便用户一些操作,特别设计自定义的用户权限管理系统. 在制作权限页面前,首先需要了解权限和用户配置权限的指令,上章讲到权限的添加,删除 ...

  8. 机器指令翻译成 JavaScript —— No.7 过渡语言

    上一篇,我们决定使用 LLVM 来优化程序,并打算用 C 作为输入语言.现在我们来研究一下,将 6502 指令转换成 C 的可行性. 跳转支持 翻译成 C 语言,可比 JS 容易多了.因为 C 支持 ...

  9. ubuntu15 coreclr

    看了很多文章心里痒痒,也下载个ubuntu想发布个asp.net5试试,自然是下载的最新版本15.结果涉及dnu restore,dnx...什么的都没反应,切换为mono就正常,奇怪了,按说core ...

  10. Thinking in Unity3D:基于物理着色(PBS)的材质系统

    关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的引擎 ...