将视图添加到 MVC 应用程序
注意
此处使用最新版本的 Visual Studio 提供了本教程的更新版本。 新教程使用 ASP.NET Core MVC,这比本教程提供了许多改进。
本教程介绍具有控制器和视图的 ASP.NET Core MVC。 Razor Pages 是 ASP.NET Core 中的一种新替代方法,它是一种基于页面的编程模型,可简化 Web UI 的生成过程并提高效率。 建议先尝试 Razor 页面教程,再使用 MVC 版本。 Razor 页面教程:
- 易于关注。
- 涵盖更多功能。
- 是新应用开发的首选方法。
在本部分中,你将修改 HelloWorldController
类以使用视图模板文件,以干净地封装生成对客户端的 HTML 响应的过程。
你将使用 Razor 视图引擎创建视图模板文件。 基于 Razor 的视图模板具有 .cshtml 文件扩展名,并提供一种使用 C# 创建 HTML 输出的优雅方法。 Razor 将编写视图模板时所需的字符数和击键次数降至最低,并支持快速、流畅的编码工作流。
当前,Index
方法返回带有在控制器类中硬编码的消息的字符串。 更改 Index
方法以调用控制器 View 方法,如以下代码所示:
public ActionResult Index()
{
return View();
}
上述 Index
方法使用视图模板生成对浏览器的 HTML 响应。 控制器方法 (也称为 操作方法) ,如 Index
上述方法,通常返回 ActionResult (或派生自 ActionResult) 的类,而不是字符串等基元类型。
右键单击“ Views\HelloWorld” 文件夹并单击“ 添加”,然后单击“ 具有布局 (Razor) 的 MVC 5 视图页 。
在“ 指定项的名称 ”对话框中,输入 “索引”,然后单击“ 确定”。
在 “选择布局页 ”对话框中,接受默认 _Layout.cshtml ,然后单击“ 确定”。
在上面的对话框中,在左窗格中选择了 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 文件,然后选择“ 在浏览器中查看”。
还可以右键单击 Index.cshtml 文件,然后选择“在Page Inspector中查看”。有关详细信息,请参阅Page Inspector教程。
或者,运行应用程序并浏览到 HelloWorld
控制器 (http://localhost:xxxx/HelloWorld
) 。 Index
控制器中的 方法没有执行太多工作;它只是运行 语句 ,该语句return View()
指定方法应使用视图模板文件来呈现对浏览器的响应。 由于未显式指定要使用的视图模板文件的名称,ASP.NET MVC 默认使用 \Views\HelloWorld 文件夹中的 Index.cshtml 视图文件。 下图显示了视图中硬编码的字符串“Hello from our View Template!”。
看起来相当不错。 但是,请注意,浏览器的标题栏显示“索引 - 我的 ASP.NET 应用程序”,并且页面顶部的大链接显示“应用程序名称”。根据浏览器窗口的较小程度,可能需要单击右上角的三个栏,才能查看“ 主页”、“ 关于”、“ 联系人”、“ 注册 ”和 “登录” 链接的 。
更改视图和布局页面
首先,需要更改页面顶部的“应用程序名称”链接。 该文本对于每一页都是通用的。 它实际上只在项目中的一个位置实现,即使它出现在应用程序的每个页面上。 转到 解决方案资源管理器 中的 /Views/Shared 文件夹,然后打开 _Layout.cshtml 文件。 此文件称为 布局页 ,它位于所有其他页面使用的共享文件夹中。
布局模板使你能够在一个位置指定网站的 HTML 容器布局,然后将它应用到网站中的多个页面。 查找 @RenderBody()
行。 RenderBody
是一个占位符,在其中显示你创建的所有视图特定的页面,“包装”在布局页面中。 例如,如果选择“ 关于” 链接,Views \Home\About.cshtml 视图将在 方法内 RenderBody
呈现。
更改标题元素的内容。 将布局模板中的 ActionLink 从“应用程序名称”更改为“MVC 电影”,将控制器从 Home
更改为 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>
</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 电影”。 单击“ 关于” 链接,你也会看到该页面如何显示“MVC 电影”。 我们能够在布局模板中进行更改一次,并让网站上的所有页面都反映新标题。
当我们第一次创建 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
,这样将不会使用任何布局文件。
现在,让我们更改“索引”视图的标题。
打开 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 视图模板) 。 请注意,布局模板 ( Views\Shared\_Layout.cshtml ) 在 元素中使用 <title>
此值作为我们之前修改的 HTML 部分的一部分 <head>
。
<!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 强制加载来自服务器的响应。) 浏览器标题是使用 ViewBag.Title
我们在 Index.cshtml 视图模板中设置的,并在布局文件中添加附加的“- 电影应用”创建。
另请注意 Index.cshtml 视图模板中的内容如何与 _Layout.cshtml 视图模板合并,并将单个 HTML 响应发送到浏览器。 凭借布局模板可以很容易地对应用程序中所有页面进行更改。
不过,我们一点点“数据” (在本例中,“来自我们的视图模板的你好!”消息) 是硬编码的。 MVC 应用程序有一个“V”(视图),而你已有一个“C”(控制器),但还没有“M”(模型)。 稍后,我们将演练如何创建数据库并从中检索模型数据。
将数据从控制器传递给视图
不过,在转到数据库并讨论模型之前,让我们先讨论如何将信息从控制器传递到视图。 调用控制器类以响应传入的 URL 请求。 控制器类用于编写代码,用于处理传入浏览器请求、从数据库中检索数据,并最终决定发送回浏览器的响应类型。 然后,可以从控制器使用视图模板来生成 HTML 响应并设置浏览器的格式。
控制器负责提供所需的任何数据或对象,以便视图模板向浏览器呈现响应。 最佳做法: 视图模板绝不应执行业务逻辑或直接与数据库交互。 相反,视图模板应仅处理控制器提供给它的数据。 保持这种“关注点分离”有助于保持代码干净、可测试且更易于维护。
目前, Welcome
类中的 HelloWorldController
操作方法采用 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
对象包含将自动传递给视图的数据。 接下来,需要一个欢迎视图模板! 在“ 生成 ”菜单中,选择“ 生成解决方案 (”或 Ctrl+Shift+B) 以确保编译项目。 右键单击 Views\HelloWorld 文件夹并单击“ 添加”,然后单击“ 布局 (Razor) 的 MVC 5 视图页 ”。
在 “指定项的名称 ”对话框中,输入“ 欢迎”,然后单击“ 确定”。
在 “选择布局页 ”对话框中,接受默认 _Layout.cshtml ,然后单击“ 确定”。
将创建 MvcMovie\Views\HelloWorld\Welcome.cshtml 文件。
替换 Welcome.cshtml 文件中的 标记。 你将创建一个循环,该循环显示“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:xx/HelloWorld/Welcome?name=Scott&numtimes=4
现在,数据从 URL 中获取,并使用 模型绑定器传递给控制器。 控制器将数据打包到 对象中, ViewBag
并将该对象传递给视图。 然后,视图以 HTML 形式向用户显示数据。
在上面的示例中,我们使用 ViewBag
对象将数据从控制器传递到视图。 稍后在本教程中,我们将使用视图模型将数据从控制器传递给视图。 传递数据的视图模型方法通常比视图包方法更优先。 有关详细信息,请参阅博客文章 Dynamic V Strongly Typed Views 。
当然,这是模型的一种“M”类型,而不是数据库类。 让我们用学到的内容来创建一个电影数据库。