ASP.NET MVC 中使用共享布局的各种方法






4.53/5 (16投票s)
在本文中,我们将讨论在 ASP.NET MVC 应用程序中使用共享布局页面的各种方法。为了实际体验,我们将创建一个演示应用程序,实现定义 ASP.NET MVC 中布局页面的不同方法。
引言
在本文中,我们将讨论在 ASP.NET MVC 应用程序中使用共享布局页面的各种方法。为了实际体验,我们将创建一个演示应用程序,实现定义 ASP.NET MVC 中布局页面的不同方法。
先决条件
要充分享受本文内容,您应该具备 C#、ASP.NET MVC、jQuery 和 HTML 的中级水平。初学者请先学习上述技术的基础知识,如有任何疑问,可以在文章下方留言。我很乐意回答您的问题。谢谢。
文章大纲
- 为什么需要共享布局页面
- 演示应用程序概述
- 使用 _ViewStart 文件和 _Layout.cshtml(默认方式):主页模块
- 在 ActionResult 中定义布局:女士模块
- 在内容页中定义布局:儿童模块
- 为目录定义布局:男士模块
- 为区域定义布局:电子产品模块
- 奖励点:为什么 _Layout.cshtml 以下划线开头
为什么需要共享布局页面
众所周知,大多数 Web 应用程序都有标志/品牌特色、导航栏、页眉、页脚以及一些广告部分(可选)等。这些元素在整个网站中都是通用的。此外,我们应该在所有网页中保持一致的外观和感觉。因此,更好的方法是将包含上述元素的元素的代码写入一个单独的文件,称为布局文件,并将该文件与其他所有网页共享。它创建了一致的外观和感觉。通过在通用的布局文件中编写共享代码,我们避免了重复,节省了时间,并且如果需要,可以在一次性更改中轻松地为所有页面进行更改。换句话说,共享布局页面引入了可重用性并提高了可维护性。
演示应用程序概述
演示应用程序分为五个模块,每个模块都遵循一种特定的方式来渲染布局页面,我们将在本文后面学习。为了快速了解我们在本文代码演示结束时将完成什么,下面是完成的应用程序的外观,其中包含指向所有五个演示的链接。在此演示中,我们将更改布局页面及其渲染方式,针对每个模块。例如,如果您单击“男士”菜单,布局页面将更改,并相应地进行渲染。
注意:我们假设您已经下载了附加的包含运行项目的示例代码。如果没有,请这样做,因为我们在这里没有提供所有代码的详细信息或屏幕截图。
创建 ASP.NET MVC 4 应用程序
在开始之前,请注意在遵循创建演示应用程序的步骤时以下几点:
- 我们将使用 Visual Studio 2012 和 ASP.NET MVC 4 来开发演示,因此在相同的设置下,附加代码将完美运行而无需任何更改。
- 我们在 Internet Explorer 10 版本和 Chrome 38 版本上测试了运行的应用程序。本文附带的屏幕截图是在 Chrome 浏览器中运行应用程序时截取的。
- 您也可以使用 Visual Studio 2013 并安装 ASP.NET MVC 4 或 5。
- 如果您使用的是旧版本的 Visual Studio/ASP.NET MVC,则需要创建类似的解决方案,并注意由于版本不同而导致的细微更改。
现在,让我们打开 Visual Studio,开始构建演示。让我们通过选择 ASP.NET MVC4 Web 应用程序模板来创建一个示例应用程序,并将项目名称命名为 LayoutDemo,然后单击 OK。项目将被创建。在下一节中,我们将了解布局页面的默认设置及其工作原理。
使用 _ViewStart 文件和 _Layout.cshtml
直到 ASP.NET MVC 2,我们还没有 _ViewStart 文件。为了提供一致的布局,我们不得不在每个视图中指定布局页面的路径。如果我们更改布局文件的名称或布局文件的位置,我们就必须修改应用程序中的所有视图/内容页面。
这就像在每个视图中重复相同的代码来应用通用布局,并且在大型应用程序中难以维护。因此,为了应对这个问题,Microsoft ASP.NET MVC 团队在 ASP.NET MVC 3 和 Razor 引擎中引入了一个名为 _ViewStart 的新文件。_ViewStart 文件在每个视图渲染的开始时执行。在此文件中的代码块内,定义了布局页面(_Layout.cshtml 文件)的路径。因此,默认情况下,此文件负责设置应用程序中视图将使用的布局页面。
让我们看看我们的演示应用程序如何默认使用 _ViewStart 和 _Layout 文件。要为 Home 模块渲染 _Layout 页面,默认情况下 _Layout 放置在 Shared 文件夹中,并且 Views 文件夹中的所有视图将使用 _ViewStart 中指定的相同 _Layout(除非另有指定或覆盖)。对于我们演示应用程序的主页,_Layout 页面是在 _ViewStart 文件的帮助下渲染的。在此主页中,使用图像来制作主页的标题,该图像放置在 Content 文件夹内的 images 文件夹中。
要渲染图像,我们需要应用一些样式并获取一些动态内容。所有必需的 CSS 都写在 custom.css 文件中,jQuery 代码写在 app.js 文件中,框架提供的一些 CSS 和 js 文件如下所示。
让我们创建一个名为 Menu 的部分视图并将其放入共享文件夹。此部分视图将用于进一步创建不同模块的链接。以下是此部分视图的代码
<nav> <ul> <li>@Html.ActionLink("Home", "Index", "Home", new { area = "" }, null))</li> <li>@Html.ActionLink("Gents", "Index", "Gents", new { area = "" }, null))</li> <li>@Html.ActionLink("Ladies", "Index", "Ladies", new { area = "" }, null))</li> <li>@Html.ActionLink("Kids", "Index", "Kids", new { area = "" }, null))</li> <li>@Html.ActionLink("Electronics", "Index", "ElectronicsHome", new { area = "Electronics" }, null)</li> </ul> </nav>
根据我们的要求修改现有的 _Layout.cshtml 文件。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> @*Bundling is used while referencing css and javascripts files*@ @Scripts.Render("~/bundles/jquery") @Styles.Render("~/Content/css") </head> <body> <div class="container"> <heade> <img src="~/Content/images/header_image/header.jpg" /> @Html.Partial("Menu") </header> <br /> <br /> <div id="pageContainer"> @RenderBody() </div> </div> </body> </html>
在上面的代码中,打包用于引用各种 CSS 和 js 文件。如果您不熟悉 ASP.NET MVC 的打包和最小化概念,请访问此处。下面的代码用于引用 CSS 和 js 文件。Bundle 在 App_Start 文件夹下的 BundleConfig.cs 文件中创建。
@Scripts.Render("~/bundles/jquery") @Styles.Render("~/Content/css")
接下来,我们使用了标题图像,然后是一个名为 Menu 的部分视图来创建菜单栏。最后,使用 @RenderBody() 方法渲染实际视图的内容,在本例中是Views/Home/Index.cshtml。
在 ActionResult 中定义布局
现在我们将从 ActionResult 渲染布局页面。在这种情况下,您需要将 _Layout 页面放在共享文件夹中,或者放在 Views 文件夹下的任何目录中。
要为女士模块渲染不同的布局页面,请向共享文件夹添加一个名为 _LadiesLayout 的布局页面,并编写与下面显示的相同的代码。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/jquery") </head> <body> <div class="container"> <header> <ul class="bxslider"> <li> <img src="../../Content/images/ladies_image/image1.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image2.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image3.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image4.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image5.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image6.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image7.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image8.jpg" alt="Slide" /> <li> <img src="../../Content/images/ladies_image/image9.jpg" alt="Slide" /> </ul> @Html.Partial("Menu") </header> <br /> <br /> <div id="pageContainer"> @RenderBody() </div> </div> <script> $(window).load(function () { $('.container').find('img').each(function () { var imgClass = (this.width / this.height > 1) ? 'wide' : 'tall'; $(this).addClass(imgClass); }) }) $('.bxslider').bxSlider({ minSlides: 4, maxSlides: 50, slideWidth: 250, ticker: true, speed: 40000 }); </script> </body> </html>
如您所见,上面的代码与我们用于 Home 模块的 _Layout.cshtml 文件相似。一些图像被引用,并且有几行代码是用 jQuery 编写的。在 _LadiesLayout 页面中,我们将渲染一个图片队列来展示女士连衣裙。为了动态渲染这些图像,我们正在使用一个名为 bxSlider 的 jQuery 插件,来自此处。这些文件在 Bundel.config 文件中引用。这里我们只是使用该插件中编写的 bxSlider 函数来控制移动图像等的速度。添加一个名为 LadiesController 的控制器,并编写与下面相同的代码。
public class LadiesController : Controller { public ActionResult Index() { return View("Index", "_LadiesLayout"); } }
此 Index 操作方法返回 Index 视图并使用 _LadiesLayout 页面。
在内容页中定义布局
要为儿童模块渲染不同的布局页面,我们将从内容页面引用布局页面。向共享文件夹添加一个名为 _KidsLayout.cshtml 的布局页面,所有代码将与 _LadiesLayout.cshtml 相同。只更改儿童图像的引用。现在像下面一样引用儿童图像。
<header> <ul class="bxslider"> <li> <img src="../../Content/images/kids_image/image1.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image2.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image3.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image4.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image5.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image6.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image7.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image8.jpg" alt="Slide" /> <li> <img src="../../Content/images/kids_image/image9.jpg" alt="Slide" /> </ul> @Html.Partial("Menu") </header>
添加一个名为 KidsController 的控制器,并编写与下面相同的代码。
public class KidsController : Controller { public ActionResult Index() { return View(); } }
右键单击 Index 操作方法以添加同名的视图。在 Index 页面中编写以下代码。
@{ Layout = "~/Views/Shared/_KidsLayout.cshtml"; } <div id="commonInfoDiv"> <b>Kids: Kids module is returning (rendering) Layout by defining Layout in each view </b> </div>
正如您所看到的,我们在 Kids 模块中为特定视图想要使用的内容视图中指定了 _KidsLayout.cshtml 布局页面的路径。现在运行应用程序,单击 Kids 模块。您将能够看到儿童图像的运行图像。
为目录定义布局
如果您遇到了这样的情况,即您想在放置在特定目录中的一组视图上应用某种特殊的布局页面。在这种情况下,您需要在同一文件夹中添加一个 _ViewStart.cshtm 和您的布局文件。为了演示这一点,添加一个名为 Gents 的控制器,我们将为 Gents 模块使用此 Gents 控制器。在此控制器中,您将获得 Index 操作方法。右键单击 Index 操作方法以添加视图。此视图将没有任何内容,只有简单的文本,例如
<div id="commonInfoDiv"> <b>Gents: Gents module is returning (rendering) Layout by adding _ViewStart and specific layout file in Gents directories </b> </div>
向 Gents 文件夹添加一个名为 _ViewStart.cshtml 的视图,并编写以下代码行
@{ Layout = "~/Views/Gents/_GentsLayout.cshtml"; }
在 Gents 文件夹中添加一个名为 _GentsLayout.cshtml 的布局页面。代码将与 _LadiesLayout.cshtml 相同,只需更改图像的引用。
<header> <ul class="bxslider"> <li> <img src="../../Content/images/gents_image/image1.jpg" alt="Slide" /> <li> <img src="../../Content/images/gents_image/image2.jpg" alt="Slide" /> <li> <img src="../../Content/images/gents_image/image3.jpg" alt="Slide" /> <li> <img src="../../Content/images/gents_image/image4.jpg" alt="Slide" /> <li> <img src="../../Content/images/gents_image/image5.jpg" alt="Slide" /> <li> <img src="../../Content/images/gents_image/image6.jpg" alt="Slide" /> <li> <img src="../../Content/images/gents_image/image7.jpg" alt="Slide" /> <li> <img src="../../Content/images/gents_image/image8.jpg" alt="Slide" /> </ul> @Html.Partial("Menu") </header>
运行应用程序,单击 Gents 模块,您应该能够看到您在 _GentsLayout.cshtml 文件中引用的运行中的男士服装图像。
为区域定义布局
在本节中,我们将了解如何在 ASP.NET MVC 应用程序中位于不同区域下的视图中应用不同的布局。如果您不熟悉区域的概念,请先查看这篇关于区域的文章。由于我在那里已经详细解释了区域,因此我将在此处简要介绍。
因此,向我们的演示应用程序添加一个名为 Electronics 的区域。然后,在 Controller 文件夹中添加一个名为 ElectronicsHome 的控制器,在 Views 文件夹中添加一个视图,在 Shared 文件夹中添加 _ElectronicsLayout,并在 Views 文件夹中添加 _ViewStart 文件。对于路由,也请更改 ElectronicsAreaAreaRegistration.cs 文件中的代码。确保在不同文件中使用与下载代码相同的代码。添加 Electronics Areas 文件夹中的文件后,文件夹结构如下所示。
完成修改后,运行演示应用程序,单击 Electronics 模块,您将获得所需的输出。
为什么 _Layout.cshtml 以下划线开头
Razor 是为ASP.NET Web Pages(WebMatrix)开发的,它不像 ASP.NET MVC 中那样内置了对 Views 文件夹和 Routing 的保护。由于 Web Pages 中的布局页面并非旨在直接提供服务,因此它们前面带有下划线。并且 Web Pages 框架已配置为不允许直接请求名称中带有前导下划线的文件。Web Pages 中的其他 .cshtml 文件通常需要可浏览。
ASP.NET 团队表示,Web Pages 是一个起点,最终可能会迁移到 MVC。这意味着现在从 Web Pages 迁移到 MVC 应该尽可能容易。因此,将 Web Pages 中建立的命名约定延续到 MVC Razor 文件是有意义的。因此,在 WebMatrix 中,在文件名中添加前导下划线有一个技术原因,但它与 MVC 无关。[这基于 Mike Brind 在Stackoverflow上的回答。]
结论
在本文中,我们了解了在 ASP.NET 应用程序中定义布局页面的各种方法。欢迎您进行讨论,请提供您的建议和意见。谢谢。