65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET MVC 4 中的区域

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (146投票s)

2014年1月22日

CPOL

8分钟阅读

viewsIcon

517498

downloadIcon

11047

在本文中,我们将学习 ASP.NET MVC 中区域的概念以及如何在实际场景中使用它。

区域简介

在本文中,我们将学习区域的概念以及如何在 ASP.NET MVC 4 的实际场景中使用它。

根据 ASP.NET MVC 项目模板的约定,为了根据职责分离应用程序代码,我们有顶级的文件夹,如ControllersViewsModels。在Controllers文件夹中,我们可以有多个控制器,每个控制器都专注于特定的功能组。在顶级的Views文件夹内部,有与控制器对应的文件夹(名称相同),其中包含该控制器的视图文件。对应于控制器中的Action名称,我们有其中的视图文件(.cshtml 文件)。最后,在顶级的Models文件夹中,我们有管理应用程序域行为和数据的模型。

这种方法对于控制器和视图数量较少的应用程序来说效果很好。随着控制器和视图数量的增加,我们会感到需要对控制器和视图进行分组。对于大型应用程序,我们经常会遇到有效组织代码的问题。在这种情况下,区域有助于我们组织代码。

区域是 MVC 应用程序中用于模块的控制器、模型、视图和其他相关文件夹的逻辑分组。根据约定,顶级的Areas文件夹可以包含多个区域。使用区域,我们可以编写更易于维护的代码,并根据模块干净地分离应用程序。

关于替代方案的讨论

有些人可能会争辩说,与其使用区域来按模块划分应用程序代码,不如在顶级的Controllers/Models/Views文件夹中创建文件夹结构。如下所示

Alternate way to achieve Modularization

但是,使用这种方法进行划分,在大型应用程序中可能会遇到以下问题:

  1. 模块的功能性质可能不同(共享代码的范围会更小),并且您可能还需要为模块的 CSS、脚本、模型和其他相关功能进行分类。您需要在每个顶级文件夹中创建相同的文件夹结构,这意味着在 Views、Models、Scripts 和 Images 等文件夹中。
  2. 如果模块需要同名的控制器,可能会出现控制器名称冲突。例如,应用程序中的许多模块可能希望拥有自己的 Home Controller。
  3. 特定模块的代码会更分散(与使用区域方法处理模块的情况相比)。

因此,区域提供了一种更优雅的方式来分离模块的代码。我们可以将模块所需的所有特定资源保存在其区域中。可重用和共享的资源可以放在 ASP.NET MVC 应用程序的相应顶级文件夹中。在下一节中,我们将了解如何在实际应用程序中使用区域。

如何避免名称冲突

假设有一个名为“Payment”的区域,它有一个“PaymentController”。在这种情况下,在使用区域时,我们需要记住以下三点,以防控制器和区域名称相同。

  1. Global.asax.cs文件中,在 `Application_Start` 方法下的 `AreaRegistration.RegisterAllAreas()` 方法必须首先被调用。
  2. RouteConfig.cs文件中,在 `RegisterRoutes` 方法下,您必须声明命名空间以避免同名控制器之间的冲突。
  3. MenAreaRegistration.cs文件中,在 `RegisterArea` 方法下,您必须声明命名空间以避免同名控制器之间的冲突。

有关另一个此类示例,请参阅此 Stack Overflow 上的问题/答案。通过下面用于演示应用程序的代码演练,上述步骤将更加清晰。

演示应用程序概述

通常,电子商务应用程序会有各种各样的产品,分为许多类别。每个产品都包含有关产品的各种信息,如制造详情、可用性、价格、可能的优惠等。在这些情况下,最好使用区域来划分应用程序模块。

在这里,为了演示,我们将开发一个简单的购物应用程序样本。该应用程序将分为三个模块:HomeMenWomen。根据一般情况,MenWomen是主要类别,它们拥有自己的子类别,如下图所示。

Modules in Demo Application

  • Home:此模块将包含有关应用程序的一般信息。这是使用项目模板附带的默认控制器/视图等实现的。这里不使用区域概念,因为它通过提供整个应用程序的界面、主页和标准信息来实现。
  • Men:此模块将包含有关Men产品的信息。这是使用 Area 概念实现的。我们在顶级的“Areas”文件夹内创建了一个“Men”区域。它拥有Men模块的所有子模块和特定主页。
  • Women:此模块将包含有关Women产品的信息。它也使用Area实现,与“Men”模块类似。

注意

  • 在演示中,我们将仅专注于如何使用区域,因此我使用了相同的 CSS 和虚拟数据。但在实际应用程序中,不同模块的显示需求可能非常具体。
  • 所有通用 CSS 文件、JS 文件和图像都放在顶级的Content文件夹中,如下所示。

    Content Folder in Demo Application

  • 为了更好地理解本文,请下载附带的代码,概述代码,然后按照本文中的步骤进行操作。

最终输出:此示例应用程序的最终输出将如下所示。

Final output of demo application

创建演示应用程序

 

让我们通过启动 Visual Studio 2012 并按照以下步骤开始:

  1. 通过选择 ASP.NET MVC4 Web Application 模板创建一个新项目,将项目名称命名为 AreaDemo,然后单击 OK。

    Choose project template for ASP.NET MVC4

  2. 选择 Basic application 模板,然后单击 OK。Visual Studio 在解决方案中添加 AreaDemo 项目,如下图所示。

    Choose Basic template MVC4 Project

  3. 首先,我们将创建应用程序的页眉和菜单。请从下载的代码中获取所需的 CSS、JavaScript 和图像。
  4. _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" />                
  5. 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>
  6. 到目前为止,菜单已创建。但是,如果我们单击菜单中的链接,将不会发生任何事情,因为我们还没有创建区域。
  7. 在解决方案资源管理器中右键单击项目(AreaDemo),然后转到 Add,再单击 Areas 选项,如下图所示。

    Add Area in Demo Application

    Areas文件夹将被添加到您的项目中。根据约定,这个顶级的Areas文件夹应该包含区域。每个区域都有自己的 Models、Views、Controllers 和areaRegistration.csareaRegistration.cs文件用于配置区域的路由。

  8. 通过右键单击刚刚创建的Areas文件夹来添加一个区域,并将新区域命名为MenMen是模块名称)。Men Area文件夹将被添加到您的项目中,如下所示。

    Add Men Area in Demo Application

    在上图中,Visual Studio 添加了ControllersModelsViews文件夹和MenAreaRegistration.cs文件。我添加了 Content 文件夹来存放Men模块所需的所有图像(从下载的代码中获取图像)。Men模块可能有子模块,就像我们有Men Clothing 和 Footwear 一样。

  9. 让我们来实现Men -> Clothing 模块。在Models文件夹下添加三个类文件,如下所示。

    Add Men Area in Demo Application

    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;
        }
    }

    上面的代码片段非常简单且易于理解,所以希望您能轻松理解。

  10. Men区域的Controllers文件夹下添加一个名为Clothing的控制器,如下图所示。

    Add controller in Men Area

    ClothingController.cs文件中的Index方法内编写以下代码。

    public ActionResult Index()
             {
                MenRepository menRepository = new MenRepository();
                var  cloths = menRepository.GetCloths();
                return View(cloths);
            } 

    Index是一个操作方法,它将返回一个具有MenClothing模型的视图,该模型包含所有Men衣服的列表。

  11. 右键单击(在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>

    上表将显示男士服装类别下的产品。

  12. 打开Global.asax.cs文件,并在Application_Start方法中。它必须包含“AreaRegistration.RegisterAllAreas();”。验证该方法是否包含此类代码。
                      protected void Application_Start()
                            {
                                AreaRegistration.RegisterAllAreas();
    
                                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                                RouteConfig.RegisterRoutes(RouteTable.Routes);
                          }                    
  13. 打开Areas > Men文件夹下的MenAreaRegistration.cs文件。此文件用于定义特定模块/区域的路由。在MapRoute方法中添加以下代码行,如下所示。
    namespaces: new[] { "AreaDemo.Areas.Men.Controllers" }

    最后,RegisterArea方法应如下所示。

    Namespace in RegisterArea

  14. 打开App_Start文件夹下的RouteConfig.cs文件,并在RegisterRoutes方法中添加以下代码行,如下所示。
    namespaces: new[] { "AreaDemo.Controllers" }

    最终的RegisterRoutes方法如下所示。

    Namespace in RegisterRoute

  15. Men (Area)模块的Controllers文件夹下再添加一个名为FootwearController的控制器(就像我们为 Clothing Controller 所做的那样)。编写以下代码,如下所示。
    public ActionResult Index()
    {
        MenRepository menRepository = new MenRepository();
        var footwears = menRepository.GetFootwears();
        return View(footwears);
    }                
  16. 右键单击(在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>
  17. Men (Area)模块的Controllers文件夹下再添加一个名为HomeController的控制器。这将是Men模块的特定主页。编写以下代码,如下所示。
    public ActionResult Index()
    {
        return View();
    }
  18. 右键单击(在刚刚创建的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>
  19. 现在运行应用程序,然后在 Men 模块下单击 Clothing。您应该会看到以下屏幕。

    Men Clothing Page p

  20. 现在单击 Men 模块下的 Footwear。您应该会看到以下屏幕。

    Men Footwears Page

  21. 要实现 women 模块,请按照从步骤 6 到 20 的相同步骤进行操作,但使用不同的数据和图像。如有任何疑问,请查看已实现两个模块的下载代码。

结论

在本文中,我们学习了如何在 ASP.NET MVC 应用程序中使用区域。这是一个非常有用的概念,可以以优雅的方式组织大型应用程序。关于这方面,您的查询和评论都非常欢迎。谢谢。

© . All rights reserved.