添加 View (2012)

作者 :Rick Anderson

注意

此处提供了本教程的更新版本,它使用 ASP.NET MVC 5 和 Visual Studio 2013。 它更安全,更易于遵循,并演示了更多功能。

在本部分中,你将修改 类, HelloWorldController 以使用视图模板文件来完全封装生成对客户端的 HTML 响应的过程。

你将使用随 ASP.NET MVC 3 一起引入的 Razor 视图引擎创建视图 模板文件。 基于 Razor 的视图模板具有 .cshtml 文件扩展名,并提供一种使用 C# 创建 HTML 输出的优雅方式。 Razor 可最大程度地减少编写视图模板时所需的字符数和击键次数,并支持快速流畅的编码工作流。

当前,Index 方法返回带有在控制器类中硬编码的消息的字符串。 Index更改 方法以返回 View 对象,如以下代码所示:

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

Index上述方法使用视图模板生成对浏览器的 HTML 响应。 控制器方法 (也称为 操作方法) ,如 Index 上述方法,通常返回 ActionResult (或派生自 ActionResult) 的类,而不是字符串等基元类型。

在 项目中,添加可与 方法一起使用的 Index 视图模板。 为此,请在 方法内右键单击, Index 然后单击“ 添加视图”。

显示在右键单击菜单中选择的“添加视图”的屏幕截图。

此时将显示 “添加视图 ”对话框。 保留默认值,然后单击“ 添加 ”按钮:

显示“添加视图”对话框的屏幕截图。索引位于“视图名称”字段中。

将创建 MvcMovie\Views\HelloWorld 文件夹和 MvcMovie\Views\HelloWorld\Index.cshtml 文件。 可以在解决方案资源管理器中查看它们:

显示解决方案资源管理器的屏幕截图。在 Hello World 子文件夹中选择了索引点 c s h t m l。

下面显示了创建的 Index.cshtml 文件:

HelloWorldIndex

在 标记下 <h2> 添加以下 HTML。

<p>Hello from our View Template!</p>

完整的 MvcMovie\Views\HelloWorld\Index.cshtml 文件如下所示。

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

如果使用 Visual Studio 2012,请在解决方案资源管理器中右键单击 Index.cshtml 文件,然后选择“在Page Inspector中查看”。

PI

Page Inspector教程详细介绍了此新工具。

或者,运行应用程序并浏览到 HelloWorld 控制器 (http://localhost:xxxx/HelloWorld) 。 Index控制器中的 方法没有执行太多工作;它只是运行 语句 ,该语句return View()指定该方法应使用视图模板文件向浏览器呈现响应。 由于未显式指定要使用的视图模板文件的名称,ASP.NET MVC 默认使用 \Views\HelloWorld 文件夹中的 Index.cshtml 视图文件。 下图显示了视图中硬编码的字符串“Hello from our View Template!”。

显示“我的 API 点 NET 索引”页的屏幕截图。

看起来相当不错。 但请注意,浏览器的标题栏显示“为我的 ASP.NET A 编制索引”,页面顶部的大链接显示“你的徽标在此处”。“此处的徽标”链接下方是注册和登录链接,下方是“主页”、“关于”和“联系人”页面的链接。 让我们更改其中的一些内容。

更改视图和布局页面

首先,你想要更改页面顶部的“你的徽标”。标题。 该文本是每个页面通用的。 它实际上只在项目中的一个位置实现,即使它出现在应用程序的每个页面上。 转到 解决方案资源管理器 中的 /Views/Shared 文件夹,然后打开 _Layout.cshtml 文件。 此文件称为 布局页 ,它是所有其他页面使用的共享“shell”。

_LayoutCshtml

布局模板使你能够在一个位置指定网站的 HTML 容器布局,然后将它应用到网站中的多个页面。 查找 @RenderBody() 行。 RenderBody 是一个占位符,其中你创建的所有特定于视图的页面都显示在布局页中“包装”。 例如,如果选择“关于”链接,则 Views\Home\About.cshtml 视图将在 方法内 RenderBody 呈现。

将布局模板中的网站标题标题从“此处的徽标”更改为“MVC Movie”。

<div class="float-left">
    <p class="site-title">@Html.ActionLink("MVC Movie", "Index", "Home")</p>
</div>

将 title 元素的内容替换为以下标记:

<title>@ViewBag.Title - Movie App</title>

运行应用程序,并注意它现在显示“MVC 电影”。 单击“ 关于 ”链接,你将看到该页面显示“MVC 电影”的方式。 我们能够在布局模板中进行更改一次,并让网站上的所有页面都反映新标题。

显示“M V C 电影关于”页的屏幕截图。

现在,让我们更改索引视图的标题。

打开 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> 此值作为我们之前修改的 HTML 部分的 <head> 一部分。 使用此方法 ViewBag ,可以轻松地在视图模板和布局文件之间传递其他参数。

运行应用程序并浏览到 http://localhost:xx/HelloWorld。 请注意,浏览器标题、主标题和辅助标题已更改。 (如果在浏览器中未看到更改,则可能正在查看缓存的内容。在浏览器中按 Ctrl+F5 强制加载来自服务器的响应。) 浏览器标题是使用我们在 Index.cshtml 视图模板中设置的ViewBag.Title,并在布局文件中添加其他“- Movie App”来创建的。

另请注意 Index.cshtml 视图模板中的内容如何与 _Layout.cshtml 视图模板合并,并将单个 HTML 响应发送到浏览器。 凭借布局模板可以很容易地对应用程序中所有页面进行更改。

显示“M V C 电影我的电影列表”页的屏幕截图。

不过,在本例中,我们少量的“数据” (“来自视图模板的 Hello!”消息) 是硬编码的。 MVC 应用程序有一个“V”(视图),而你已有一个“C”(控制器),但还没有“M”(模型)。 稍后,我们将演练如何创建数据库并从中检索模型数据。

将数据从控制器传递给视图

不过,在转到数据库并讨论模型之前,让我们先讨论一下将信息从控制器传递到视图。 调用控制器类以响应传入的 URL 请求。 控制器类用于编写代码,用于处理传入的浏览器请求、从数据库中检索数据,并最终决定将哪种类型的响应发送回浏览器。 然后,可以从控制器使用视图模板来生成 HTML 响应并设置浏览器的格式。

控制器负责提供视图模板向浏览器呈现响应所需的任何数据或对象。 最佳做法: 视图模板绝不应执行业务逻辑或直接与数据库交互。 相反,视图模板应仅处理控制器提供给它的数据。 保持这种“关注点分离”有助于保持代码干净、可测试且更易于维护。

目前, Welcome 类中的 HelloWorldController 操作方法采用 namenumTimes 参数,然后将值直接输出到浏览器。 让我们将控制器更改为使用视图模板,而不是让控制器将此响应呈现为字符串。 视图模板将生成动态响应,这意味着你需要将适当的数据位从控制器传递给视图以生成响应。 为此,可以让控制器将动态数据 (参数) 视图模板所需的对象中 ViewBag ,视图模板随后可以访问该对象。

返回到 HelloWorldController.cs 文件,并更改 Welcome 方法以向 对象添加 MessageNumTimesViewBagViewBag 是一个动态对象,这意味着你可以将任何你想要的对象放入其中;对象没有定义的属性, ViewBag 直到你在其中放置一些内容。 ASP.NET MVC 模型绑定系统自动将命名参数 (namenumTimes) 从地址栏中的查询字符串映射到方法中的参数。 完整的 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 对象包含将自动传递给视图的数据。

接下来,需要一个欢迎视图模板! 在“ 生成 ”菜单中,选择“ 生成 MvcMovie ”以确保已编译项目。

然后右键单击 方法内部, Welcome 并单击“ 添加视图”。

显示“Hello World控制器点 c”选项卡的屏幕截图。在“解决方案资源管理器”窗口中,“添加视图”在“Hello World控制器点 c 右键菜单中处于选中状态。

添加视图 ”对话框如下所示:

显示“添加视图”对话框的屏幕截图。“欢迎”位于“视图名称”字段中。

单击“添加”,然后在新的 Welcome.cshtml 文件中的 <h2> 元素下添加以下代码。 你将创建一个循环,该循环显示“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 形式向用户显示数据。

显示“M V C 电影欢迎”页的屏幕截图。

在上面的示例中,我们使用 ViewBag 对象将数据从控制器传递到视图。 在本教程的后面部分,我们将使用视图模型将数据从控制器传递到视图。 传递数据的视图模型方法通常比视图包方法更优先。 有关详细信息,请参阅博客文章 Dynamic V Strongly Typed Views

当然,这是模型的一种“M”类型,而不是数据库类。 让我们用学到的内容来创建一个电影数据库。