ASP.NET MVC 4 中的区域






4.74/5 (146投票s)
在本文中,我们将学习 ASP.NET MVC 中区域的概念以及如何在实际场景中使用它。
区域简介
在本文中,我们将学习区域的概念以及如何在 ASP.NET MVC 4 的实际场景中使用它。
根据 ASP.NET MVC 项目模板的约定,为了根据职责分离应用程序代码,我们有顶级的文件夹,如Controllers、Views和Models。在Controllers文件夹中,我们可以有多个控制器,每个控制器都专注于特定的功能组。在顶级的Views文件夹内部,有与控制器对应的文件夹(名称相同),其中包含该控制器的视图文件。对应于控制器中的Action名称,我们有其中的视图文件(.cshtml 文件)。最后,在顶级的Models文件夹中,我们有管理应用程序域行为和数据的模型。
这种方法对于控制器和视图数量较少的应用程序来说效果很好。随着控制器和视图数量的增加,我们会感到需要对控制器和视图进行分组。对于大型应用程序,我们经常会遇到有效组织代码的问题。在这种情况下,区域有助于我们组织代码。
区域是 MVC 应用程序中用于模块的控制器、模型、视图和其他相关文件夹的逻辑分组。根据约定,顶级的Areas文件夹可以包含多个区域。使用区域,我们可以编写更易于维护的代码,并根据模块干净地分离应用程序。
关于替代方案的讨论
有些人可能会争辩说,与其使用区域来按模块划分应用程序代码,不如在顶级的Controllers/Models/Views文件夹中创建文件夹结构。如下所示
但是,使用这种方法进行划分,在大型应用程序中可能会遇到以下问题:
- 模块的功能性质可能不同(共享代码的范围会更小),并且您可能还需要为模块的 CSS、脚本、模型和其他相关功能进行分类。您需要在每个顶级文件夹中创建相同的文件夹结构,这意味着在 Views、Models、Scripts 和 Images 等文件夹中。
- 如果模块需要同名的控制器,可能会出现控制器名称冲突。例如,应用程序中的许多模块可能希望拥有自己的 Home Controller。
- 特定模块的代码会更分散(与使用区域方法处理模块的情况相比)。
因此,区域提供了一种更优雅的方式来分离模块的代码。我们可以将模块所需的所有特定资源保存在其区域中。可重用和共享的资源可以放在 ASP.NET MVC 应用程序的相应顶级文件夹中。在下一节中,我们将了解如何在实际应用程序中使用区域。
如何避免名称冲突
假设有一个名为“Payment
”的区域,它有一个“PaymentController
”。在这种情况下,在使用区域时,我们需要记住以下三点,以防控制器和区域名称相同。
- 在Global.asax.cs文件中,在 `Application_Start` 方法下的 `AreaRegistration.RegisterAllAreas()` 方法必须首先被调用。
- 在RouteConfig.cs文件中,在 `RegisterRoutes` 方法下,您必须声明命名空间以避免同名控制器之间的冲突。
- 在MenAreaRegistration.cs文件中,在 `RegisterArea` 方法下,您必须声明命名空间以避免同名控制器之间的冲突。
有关另一个此类示例,请参阅此 Stack Overflow 上的问题/答案。通过下面用于演示应用程序的代码演练,上述步骤将更加清晰。
演示应用程序概述
通常,电子商务应用程序会有各种各样的产品,分为许多类别。每个产品都包含有关产品的各种信息,如制造详情、可用性、价格、可能的优惠等。在这些情况下,最好使用区域来划分应用程序模块。
在这里,为了演示,我们将开发一个简单的购物应用程序样本。该应用程序将分为三个模块:Home
、Men
和Women
。根据一般情况,Men
和Women
是主要类别,它们拥有自己的子类别,如下图所示。
- Home:此模块将包含有关应用程序的一般信息。这是使用项目模板附带的默认控制器/视图等实现的。这里不使用区域概念,因为它通过提供整个应用程序的界面、主页和标准信息来实现。
- Men:此模块将包含有关
Men
产品的信息。这是使用 Area 概念实现的。我们在顶级的“Areas”文件夹内创建了一个“Men
”区域。它拥有Men
模块的所有子模块和特定主页。 - Women:此模块将包含有关
Women
产品的信息。它也使用Area
实现,与“Men
”模块类似。
注意
- 在演示中,我们将仅专注于如何使用区域,因此我使用了相同的 CSS 和虚拟数据。但在实际应用程序中,不同模块的显示需求可能非常具体。
- 所有通用 CSS 文件、JS 文件和图像都放在顶级的Content文件夹中,如下所示。
- 为了更好地理解本文,请下载附带的代码,概述代码,然后按照本文中的步骤进行操作。
最终输出:此示例应用程序的最终输出将如下所示。
创建演示应用程序
让我们通过启动 Visual Studio 2012 并按照以下步骤开始:
- 通过选择 ASP.NET MVC4 Web Application 模板创建一个新项目,将项目名称命名为 AreaDemo,然后单击 OK。
- 选择 Basic application 模板,然后单击 OK。Visual Studio 在解决方案中添加 AreaDemo 项目,如下图所示。
- 首先,我们将创建应用程序的页眉和菜单。请从下载的代码中获取所需的 CSS、JavaScript 和图像。
- 在_Layout.cshtml文件中需要一些引用,如下所示。
<script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/Content/appjs/animation.js"></script> <link href="~/Content/appcss/navigation.css" rel="stylesheet" /> <link href="~/Content/appcss/animation.css" rel="stylesheet" /> <link href="~/Content/appcss/custom.css" rel="stylesheet" />
- 在Shared文件夹中的_Layout.cshtml文件中修改代码,如下所示。它将为所有屏幕提供通用的布局(页眉和菜单)。
<body> <div id="container"> <header id="pageHeader"> <img src="~/Content/images/header.jpg" /> <nav> <ul> <li><a href="https://codeproject.org.cn/">Home</a></li> <li><a href="~/Men/Home/Index">Men</a> <ul> <li><a href="~/Men/Clothing/Index">Clothing</a></li> <li><a href="~/Men/Footwear/Index">Footwears</a></li> </ul> </li> <li><a href="~/Women/Home/Index">Women</a> <ul> <li><a href="~/Women/Clothing/Index">Clothing</a></li> <li><a href="~/Women/Footwear/Index">Footwears</a></li> </ul> </li> </ul> </nav> </header> <br /> <br /> <div id="pageContainer"> @RenderBody() </div> </div> </body>
- 到目前为止,菜单已创建。但是,如果我们单击菜单中的链接,将不会发生任何事情,因为我们还没有创建区域。
- 在解决方案资源管理器中右键单击项目(
AreaDemo
),然后转到 Add,再单击 Areas 选项,如下图所示。Areas文件夹将被添加到您的项目中。根据约定,这个顶级的Areas文件夹应该包含区域。每个区域都有自己的 Models、Views、Controllers 和areaRegistration.cs。areaRegistration.cs文件用于配置区域的路由。
- 通过右键单击刚刚创建的Areas文件夹来添加一个区域,并将新区域命名为
Men
(Men
是模块名称)。Men Area文件夹将被添加到您的项目中,如下所示。在上图中,Visual Studio 添加了Controllers、Models、Views文件夹和MenAreaRegistration.cs文件。我添加了 Content 文件夹来存放
Men
模块所需的所有图像(从下载的代码中获取图像)。Men
模块可能有子模块,就像我们有Men
Clothing 和 Footwear 一样。 - 让我们来实现
Men
-> Clothing 模块。在Models文件夹下添加三个类文件,如下所示。在MenClothing.cs文件中编写以下代码。
public class MenClothing { public int Id { get; set; } public string Name { get; set; } public int Size { get; set; } public double Price { get; set; } public string imageURL { get; set; } }
在MenFootwear.cs文件中编写以下代码。
public class MenFootwear { public int Id { get; set; } public string Name { get; set; } public int Size { get; set; } public double Price { get; set; } public string imageURL { get; set; } }
在MenRepository.cs文件中编写以下代码。
public class MenRepository { public List<MenClothing> GetCloths() { List<MenClothing> result = new List<MenClothing> { new MenClothing () { Id = 1, Name = "Formal Shirt", Size= 40, Price = 1200, imageURL="/Areas/Men/Content/images/men_cloths/img_c1.jpg"}, new MenClothing () { Id = 2, Name = "Jeans Pant", Size= 36, Price = 2200, imageURL="/Areas/Men/Content/images/men_cloths/img_c2.jpg"}, new MenClothing () { Id = 3, Name = "Casual Shirt", Size= 40, Price = 1000, imageURL="/Areas/Men/Content/images/men_cloths/img_c3.jpg"}, new MenClothing () { Id = 4, Name = "Formal Pant", Size= 36, Price = 1299, imageURL="/Areas/Men/Content/images/men_cloths/img_c4.jpg"} }; return result; } public List<MenFootwear> GetFootwears() { List<MenFootwear> result = new List<MenFootwear> { new MenFootwear () { Id = 1, Name = "Casual Slipper", Size= 8, Price = 1200, imageURL="/Areas/Men/Content/images/men_footwears/img_f1.jpg"}, new MenFootwear () { Id = 2, Name = "Casual Slipper", Size= 9, Price = 2200, imageURL="/Areas/Men/Content/images/men_footwears/img_f2.jpg"}, new MenFootwear () { Id = 3, Name = "Casual Shoes", Size= 9, Price = 2500, imageURL="/Areas/Men/Content/images/men_footwears/img_f3.jpg"}, new MenFootwear () { Id = 4, Name = "Formal Shoes", Size= 9, Price = 1600, imageURL="/Areas/Men/Content/images/men_footwears/img_f4.jpg"} }; return result; } }
上面的代码片段非常简单且易于理解,所以希望您能轻松理解。
- 在
Men
区域的Controllers文件夹下添加一个名为Clothing的控制器,如下图所示。在ClothingController.cs文件中的
Index
方法内编写以下代码。public ActionResult Index() { MenRepository menRepository = new MenRepository(); var cloths = menRepository.GetCloths(); return View(cloths); }
Index
是一个操作方法,它将返回一个具有MenClothing
模型的视图,该模型包含所有Men
衣服的列表。 - 右键单击(在ClothingController.cs中)
Index
操作方法以添加视图,并遵循默认选项。它将在Views > Clothing文件夹中添加Index.cshtml文件。在该视图中使用MenClothing
模型编写以下代码,如下所示。@model IEnumerable<AreaDemo.Areas.Men.Models.MenClothing> @{ Layout = "~/Views/Shared/_Layout.cshtml"; } <h3 > Men Clothings</h3> <table class="tblStyle"> <tr class="tblHearerRow"> <th class="tblHearerCell">Product </th> <th class="tblHearerCell">Price </th> <th class="tblHearerCell">Size </th> <th class="tblHearerCell">Images </th> </tr> @foreach (var item in Model) { <tr class="tblRow"> <td class="tblColumn"> @Html.DisplayFor(modelItem => item.Name) </td> <td class="tblColumn"> @Html.DisplayFor(modelItem => item.Price) </td> <td class="tblColumn"> @Html.DisplayFor(modelItem => item.Size) </td> <td class="tblColumn"> <div class="thumbnail-item"> <a href="#"> <img src="@item.imageURL" class="thumbnail" /> </a> <div class="tooltip"> <img src="@item.imageURL" alt="" class="imageShadow" /> <span class="overlay"></span> </div> </div> </td> </tr> } </table>
上表将显示男士服装类别下的产品。
- 打开Global.asax.cs文件,并在
Application_Start
方法中。它必须包含“AreaRegistration.RegisterAllAreas();
”。验证该方法是否包含此类代码。protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); }
- 打开Areas > Men文件夹下的MenAreaRegistration.cs文件。此文件用于定义特定模块/区域的路由。在
MapRoute
方法中添加以下代码行,如下所示。namespaces: new[] { "AreaDemo.Areas.Men.Controllers" }
最后,
RegisterArea
方法应如下所示。 - 打开App_Start文件夹下的RouteConfig.cs文件,并在
RegisterRoutes
方法中添加以下代码行,如下所示。namespaces: new[] { "AreaDemo.Controllers" }
最终的
RegisterRoutes
方法如下所示。 - 在
Men (Area)
模块的Controllers文件夹下再添加一个名为FootwearController
的控制器(就像我们为 Clothing Controller 所做的那样)。编写以下代码,如下所示。public ActionResult Index() { MenRepository menRepository = new MenRepository(); var footwears = menRepository.GetFootwears(); return View(footwears); }
- 右键单击(在FootwearController.cs中)
Index
操作方法以添加视图,并遵循默认选项。它将在Views > Footwear文件夹中添加Index.cshtml文件。此视图将显示所有男士鞋类。在Index.cshtml文件中编写以下代码,如下所示。@model IEnumerable<AreaDemo.Areas.Men.Models.MenFootwear> @{ Layout = "~/Views/Shared/_Layout.cshtml"; } <h3> Men Footwears</h3> <table class="tblStyle"> <tr class="tblHearerRow"> <th class="tblHearerCell">Product </th> <th class="tblHearerCell">Price </th> <th class="tblHearerCell">Size </th> <th class="tblHearerCell">Images </th> </tr> @foreach (var item in Model) { <tr class="tblRow"> <td class="tblColumn"> @Html.DisplayFor(modelItem => item.Name) </td> <td class="tblColumn"> @Html.DisplayFor(modelItem => item.Price) </td> <td class="tblColumn"> @Html.DisplayFor(modelItem => item.Size) </td> <td class="tblColumn"> <div class="thumbnail-item"> <a href="#"> <img src="@item.imageURL" class="thumbnail" /> </a> <div class="tooltip"> <img src="@item.imageURL" alt="" class="imageShadow" /> <span class="overlay"></span> </div> </div> </td> </tr> } </table>
- 在
Men (Area)
模块的Controllers文件夹下再添加一个名为HomeController
的控制器。这将是Men
模块的特定主页。编写以下代码,如下所示。public ActionResult Index() { return View(); }
- 右键单击(在刚刚创建的HomeController.cs中)
Index
操作方法以添加视图,并遵循默认选项。它将在 Views > Home 文件夹中添加Index.cshtml文件。在此文件中编写以下代码,如下所示。@{ Layout = "~/Views/Shared/_Layout.cshtml"; } <div id="homeDiv"> <h2>This is home page for Men module. To view the products in Men module, please select a category from top menu. </h2> </div>
- 现在运行应用程序,然后在 Men 模块下单击 Clothing。您应该会看到以下屏幕。
p
- 现在单击 Men 模块下的 Footwear。您应该会看到以下屏幕。
- 要实现 women 模块,请按照从步骤 6 到 20 的相同步骤进行操作,但使用不同的数据和图像。如有任何疑问,请查看已实现两个模块的下载代码。
结论
在本文中,我们学习了如何在 ASP.NET MVC 应用程序中使用区域。这是一个非常有用的概念,可以以优雅的方式组织大型应用程序。关于这方面,您的查询和评论都非常欢迎。谢谢。