ASP.NET Core 中的區域

作者:Dhananjay KumarRick Anderson

區域是 ASP.NET 功能,用來將相關功能組織成個別的群組:

  • 路由的命名空間。
  • 檢視和 Razor 頁面的資料夾結構。

使用區域可藉由將另一個路由參數 、 area 和 或 Page page 新增至 controlleractionRazor 以建立階層以用於路由。

區域可讓您將 ASP.NET Core Web 應用程式分割成較小的功能群組,每個群組都有自己的一組 Razor 頁面、控制器、檢視和模型。 一個區域基本上是應用程式內的一個結構。 在 ASP.NET Core Web 專案中,Pages、模型、控制器和檢視等邏輯元件都會保留在不同的資料夾中。 ASP.NET Core 執行階段會使用命名慣例來建立這些元件之間的關聯性。 針對大型應用程式,將應用程式分割成個別高功能層級區域可能較有利。 舉例來說,一個電子商務應用程式可具有多個業務單位,例如結帳、計費和搜尋。 每個單位都有自己的區域,以包含檢視、控制器、 Razor 頁面和模型。

處於下列情況時,請考慮在專案中使用區域:

  • 應用程式是由可以邏輯方式區隔的多個高階功能性元件所組成的。
  • 您想要分割應用程式,讓每個功能區域都可獨立運作。

如果您使用 Razor Pages,請參閱本檔中 具有 Razor 頁面的區域

適用於控制器與檢視的區域

使用區域、控制器及檢視的典型 ASP.NET Core Web 應用程式包含下列項目:

  • 一個區域資料夾結構

  • 具有 屬性的 [Area] 控制器,可將控制器與區域產生關聯:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • 新增至 Program.cs 的區域路由

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllersWithViews();
    
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapControllerRoute(
        name: "MyArea",
        pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    
    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    
    app.Run();
    

區域資料夾結構

假設應用程式具有兩個邏輯群組:「產品」和「服務」。 使用區域,資料夾結構應該如下:

  • 專案名稱
    • 區域
      • 產品
        • 控制器
          • HomeController.cs
          • ManageController.cs
        • 檢視
          • Home
            • Index.cshtml
          • 管理
            • Index.cshtml
            • About.cshtml
      • 服務
        • 控制器
          • HomeController.cs
        • 檢視
          • Home
            • Index.cshtml

儘管上述配置通常會在使用區域時使用,但是只需有檢視檔案,就能使用此資料夾結構。 檢視探索會依下列順序搜尋相符的區域檢視檔案:

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

使控制器與區域產生關聯

區網域控制站是使用 [Area] 屬性來指定:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Docs.Samples;

namespace MVCareas.Areas.Products.Controllers;

[Area("Products")]
public class ManageController : Controller
{
    public IActionResult Index()
    {
        ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
        return View();
    }

    public IActionResult About()
    {
        ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
        return View();
    }
}

新增區域路由

區域路由通常會使用 傳統路由 ,而不是 屬性路由。 慣例路由與順序息息相關。 一般而言,具有區域的路由應該放在路由表前面,因為這些路由比沒有區域的路由更明確。

如果 URL 空間在所有區域中都是統一的,則可使用 {area:...} 作為路由範本中的語彙基元:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "MyArea",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

在上述程式碼中,exists 會套用路由必須與區域相符的條件約束。 搭配 MapControllerRoute 使用 {area:...}

  • 這是將路由新增至區域的最低複雜機制。
  • 比對所有控制器與 [Area("Area name")] 屬性。

下列程式碼會使用 MapAreaControllerRoute 來建立兩個具名的區域路由:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapAreaControllerRoute(
    name: "MyAreaProducts",
    areaName: "Products",
    pattern: "Products/{controller=Home}/{action=Index}/{id?}");

app.MapAreaControllerRoute(
    name: "MyAreaServices",
    areaName: "Services",
    pattern: "Services/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

如需詳細資訊,請參閱區域路由

以下來自範例下載的程式碼會顯示使用指定的區域來產生連結:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage",
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

範例下載包含部分 檢視 ,其中包含:

  • 上述連結。
  • 未指定類似上述的連結 area

部分檢視會在配置檔案中進行參考,因此,應用程式中的每個頁面都會顯示產生的連結。 在未指定區域的情況下產生的連結,只有在從相同區域與控制器中的頁面進行參考時才有效。

未指定區域或控制站時,路由即會取決於「環境」值。 目前要求的目前路由值被視為用於連結產生的環境值。 在許多情況下,使用環境值會產生不正確的連結與未指定區域的標記。

如需詳細資訊,請參閱路由至控制器動作

使用 _ViewStart.cshtml 檔案共用區域的配置

若要共用整個應用程式的通用配置,請將 _ViewStart.cshtml 保留在 應用程式根資料夾中。 如需詳細資訊,請參閱ASP.NET Core 中的版面配置

應用程式根資料夾

應用程式根資料夾是資料夾,其中包含 Program.cs 使用 ASP.NET Core 範本建立的 Web 應用程式中的檔案。

_ViewImports.cshtml

/Views/_ViewImports.cshtml,適用于 MVC 和 /Pages/_ViewImports.cshtml for Razor Pages,不會匯入區域中的檢視。 使用下列其中一種方法來提供檢視匯入至所有檢視:

  • _ViewImports.cshtml 新增至 應用程式根資料夾。 應用程式根資料夾中 的 _ViewImports.cshtml 會套用至應用程式中的所有檢視。
  • _ViewImports.cshtml 檔案複製到區域下方的適當檢視資料夾。 例如, Razor 以個別使用者帳戶建立的 Pages 應用程式具有下列資料夾中 的 _ViewImports.cshtml 檔案:
    • /Areas/ Identity /Pages/_ViewImports.cshtml
    • /Pages/_ViewImports.cshtml

_ViewImports.cshtml檔案通常包含標籤協助程式匯入、 @using@inject 語句。 如需詳細資訊,請參閱 匯入共用指示詞

變更檢視儲存所在的預設區域資料夾

下列程式碼會將預設的區域資料夾從 "Areas" 變更為 "MyAreas"

using Microsoft.AspNetCore.Mvc.Razor;

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<RazorViewEngineOptions>(options =>
{
    options.AreaViewLocationFormats.Clear();
    options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
    options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
    options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
});

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "MyArea",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

具有 Razor 頁面的區域

具有 Razor Pages 的區域需要 Areas/<area name>/Pages 應用程式根目錄中的資料夾。 下列資料夾結構搭配範例應用程式一起使用:

  • 專案名稱
    • 區域
      • 產品
        • 頁面
          • _ViewImports
          • 關於
          • 索引
      • 服務
        • 頁面
          • 管理
            • 關於
            • 索引

以下來自範例下載的程式碼會顯示使用指定的區域 (例如 asp-area="Products") 來產生連結:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

範例下載包括部分檢視,其中可在未指定區域的情況下包含上述連結和相同連結。 部分檢視會在配置檔案中進行參考,因此,應用程式中的每個頁面都會顯示產生的連結。 在未指定區域的情況下產生的連結,只有在從相同區域中的頁面進行參考時才有效。

未指定區域時,路由即會取決於「環境」值。 目前要求的目前路由值被視為用於連結產生的環境值。 在許多適用於範例應用程式的案例中,使用環境值會產生不正確的連結。 例如,試想從下列程式碼產生的連結:

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

針對上述程式碼:

  • 僅當最後一個要求是針對 Services 區域中的頁面時,從 <a asp-page="/Manage/About"> 產生的連結才是正確的。 例如,/Services/Manage//Services/Manage/Index/Services/Manage/About
  • 僅當最後一個要求是針對 /Home 中的頁面時,從 <a asp-page="/About"> 產生的連結才是正確的。
  • 程式碼來自下載範例

使用 _ViewImports 檔案匯入命名空間和標記協助程式

_ViewImports.cshtml檔案可以新增至每個區域Pages資料夾,以將命名空間和標籤協助程式匯入資料夾中的每個 Razor 頁面。

請考慮範例程式碼的 Services 區域,該區域不包含 _ViewImports.cshtml 檔案。 下列標記顯示/Services/Manage/AboutRazor Page:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<div>
  ViewData["routeInfo"]:  @ViewData["routeInfo"]
</div>

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

在上述標記中:

  • 完整類別名稱必須用來指定模型 () @model RPareas.Areas.Services.Pages.Manage.AboutModel
  • 標記協助程式@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 啟用

在範例下載中,Products 區域包含下列 _ViewImports.cshtml 檔案:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

下列標記顯示/Products/AboutRazor Page:

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

在上述檔案中,命名空間和 @addTagHelper 指示詞會由 Areas/Products/Pages/_ViewImports.cshtml 檔案匯入到檔案。

如需詳細資訊,請參閱管理標籤協助程式範圍匯入共用指示詞

頁面區域的共用版面配置 Razor

若要針對整個應用程式共用通用的配置,請將 _ViewStart.cshtml 移至應用程式根資料夾。

發行區域

當 *.csproj 檔案中包含 <Project Sdk="Microsoft.NET.Sdk.Web"> 時,會將所有 *.cshtml 檔案及 wwwroot 目錄內的檔案發佈至輸出。

使用 Visual Studio 新增 MVC 區域

在方案總管中,以滑鼠右鍵按一下專案,然後選取 [新增 > Scaffolded 專案],然後選取[MVC 區域]。

其他資源

區域是 ASP.NET 功能,用來將相關功能組織成個別的群組:

  • 路由的命名空間。
  • 檢視和 Razor 頁面的資料夾結構。

使用區域可藉由將另一個路由參數 、 area 和 或 Page page 新增至 controlleractionRazor 以建立階層以用於路由。

區域可讓您將 ASP.NET Core Web 應用程式分割成較小的功能群組,每個群組都有自己的一組 Razor 頁面、控制器、檢視和模型。 一個區域基本上是應用程式內的一個結構。 在 ASP.NET Core Web 專案中,Pages、模型、控制器和檢視等邏輯元件都會保留在不同的資料夾中。 ASP.NET Core 執行階段會使用命名慣例來建立這些元件之間的關聯性。 針對大型應用程式,將應用程式分割成個別高功能層級區域可能較有利。 舉例來說,一個電子商務應用程式可具有多個業務單位,例如結帳、計費和搜尋。 每個單位都有自己的區域,以包含檢視、控制器、 Razor 頁面和模型。

處於下列情況時,請考慮在專案中使用區域:

  • 應用程式是由可以邏輯方式區隔的多個高階功能性元件所組成的。
  • 您想要分割應用程式,讓每個功能區域都可獨立運作。

檢視或下載範例程式碼 (如何下載)。 下載範例提供基本的應用程式來測試區域。

如果您使用 Razor Pages,請參閱本檔中 具有 Razor 頁面的區域

適用於控制器與檢視的區域

使用區域、控制器及檢視的典型 ASP.NET Core Web 應用程式包含下列項目:

  • 一個區域資料夾結構

  • 具有 屬性的 [Area] 控制器,可將控制器與區域產生關聯:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • 新增至啟動的區域路由

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "MyArea",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
    

區域資料夾結構

假設應用程式具有兩個邏輯群組:「產品」和「服務」。 使用區域,資料夾結構應該如下:

  • 專案名稱
    • 區域
      • 產品
        • 控制器
          • HomeController.cs
          • ManageController.cs
        • 檢視
          • Home
            • Index.cshtml
          • 管理
            • Index.cshtml
            • About.cshtml
      • 服務
        • 控制器
          • HomeController.cs
        • 檢視
          • Home
            • Index.cshtml

儘管上述配置通常會在使用區域時使用,但是只需有檢視檔案,就能使用此資料夾結構。 檢視探索會依下列順序搜尋相符的區域檢視檔案:

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

使控制器與區域產生關聯

區網域控制站是使用 [Area] 屬性來指定:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Docs.Samples;

namespace MVCareas.Areas.Products.Controllers
{
    [Area("Products")]
    public class ManageController : Controller
    {
        public IActionResult Index()
        {
            ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
            return View();
        }

        public IActionResult About()
        {
            ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
            return View();
        }
    }
}

新增區域路由

區域路由通常會使用 傳統路由 ,而不是 屬性路由。 慣例路由與順序息息相關。 一般而言,具有區域的路由應該放在路由表前面,因為這些路由比沒有區域的路由更明確。

如果 URL 空間在所有區域中都是統一的,則可使用 {area:...} 作為路由範本中的語彙基元:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "MyArea",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

在上述程式碼中,exists 會套用路由必須與區域相符的條件約束。 搭配 MapControllerRoute 使用 {area:...}

  • 這是將路由新增至區域的最低複雜機制。
  • 比對所有控制器與 [Area("Area name")] 屬性。

下列程式碼會使用 MapAreaControllerRoute 來建立兩個具名的區域路由:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapAreaControllerRoute(
            name: "MyAreaProducts",
            areaName: "Products",
            pattern: "Products/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapAreaControllerRoute(
            name: "MyAreaServices",
            areaName: "Services",
            pattern: "Services/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

如需詳細資訊,請參閱區域路由

以下來自範例下載的程式碼會顯示使用指定的區域來產生連結:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage",
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

範例下載包含部分 檢視 ,其中包含:

  • 上述連結。
  • 未指定類似上述的連結 area

部分檢視會在配置檔案中進行參考,因此,應用程式中的每個頁面都會顯示產生的連結。 在未指定區域的情況下產生的連結,只有在從相同區域與控制器中的頁面進行參考時才有效。

未指定區域或控制站時,路由即會取決於「環境」值。 目前要求的目前路由值被視為用於連結產生的環境值。 在許多情況下,使用環境值會產生不正確的連結,且標記未指定區域。

如需詳細資訊,請參閱路由至控制器動作

使用 _ViewStart.cshtml 檔案共用區域的配置

若要共用整個應用程式的通用配置,請將 保留在 _ViewStart.cshtml應用程式根資料夾中。 如需詳細資訊,請參閱ASP.NET Core 中的版面配置

應用程式根資料夾

應用程式根資料夾是包含在使用 ASP.NET Core 範本建立的 Web 應用程式中的資料夾 Startup.cs

_ViewImports.cshtml

/Views/_ViewImports.cshtml針對 MVC 和 /Pages/_ViewImports.cshtmlRazor Pages,不會匯入到區域中的檢視。 使用下列其中一種方法,將檢視匯入提供給所有檢視:

  • 將 新增 _ViewImports.cshtml應用程式根資料夾_ViewImports.cshtml應用程式根資料夾中的 會套用至應用程式中的所有檢視。
  • 將檔案 _ViewImports.cshtml 複製到區域下方的適當檢視資料夾。

檔案 _ViewImports.cshtml 通常包含 標籤協助程式 匯入、 @using@inject 語句。 如需詳細資訊,請參閱 匯入共用指示詞

變更檢視儲存所在的預設區域資料夾

下列程式碼會將預設的區域資料夾從 "Areas" 變更為 "MyAreas"

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.AreaViewLocationFormats.Clear();
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
    });

    services.AddControllersWithViews();
}

具有 Razor 頁面的區域

具有 Razor Pages 的區域需要 Areas/<area name>/Pages 應用程式根目錄中的資料夾。 下列資料夾結構搭配範例應用程式一起使用:

  • 專案名稱
    • 區域
      • 產品
        • 頁面
          • _ViewImports
          • 關於
          • 索引
      • 服務
        • 頁面
          • 管理
            • 關於
            • 索引

以下來自範例下載的程式碼會顯示使用指定的區域 (例如 asp-area="Products") 來產生連結:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

範例下載包括部分檢視,其中可在未指定區域的情況下包含上述連結和相同連結。 部分檢視會在配置檔案中進行參考,因此,應用程式中的每個頁面都會顯示產生的連結。 在未指定區域的情況下產生的連結,只有在從相同區域中的頁面進行參考時才有效。

未指定區域時,路由即會取決於「環境」值。 目前要求的目前路由值被視為用於連結產生的環境值。 在許多適用於範例應用程式的案例中,使用環境值會產生不正確的連結。 例如,試想從下列程式碼產生的連結:

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

針對上述程式碼:

  • 僅當最後一個要求是針對 Services 區域中的頁面時,從 <a asp-page="/Manage/About"> 產生的連結才是正確的。 例如,/Services/Manage//Services/Manage/Index/Services/Manage/About
  • 僅當最後一個要求是針對 /Home 中的頁面時,從 <a asp-page="/About"> 產生的連結才是正確的。
  • 程式碼來自下載範例

使用 _ViewImports 檔案匯入命名空間和標記協助程式

您可以將檔案 _ViewImports.cshtml 新增至每個區域 Pages 資料夾,以將命名空間和標籤協助程式匯入資料夾中的每一 Razor 個頁面。

請考慮範例程式碼 的服務區域, 其中不包含檔案 _ViewImports.cshtml 。 下列標記顯示/Services/Manage/AboutRazor Page:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

在上述標記中:

  • 完整類別名稱必須用來指定模型 (@model RPareas.Areas.Services.Pages.Manage.AboutModel) 。
  • 標記協助程式@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 啟用

在範例下載中,Products 區域包含下列 _ViewImports.cshtml 檔案:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

下列標記顯示/Products/AboutRazor Page:

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

在上述檔案中,命名空間和 @addTagHelper 指示詞會由 Areas/Products/Pages/_ViewImports.cshtml 檔案匯入檔案。

如需詳細資訊,請參閱管理標籤協助程式範圍匯入共用指示詞

頁面區域的 Razor 共用版面配置

若要共用整個應用程式的通用配置,請將 移至 _ViewStart.cshtml 應用程式根資料夾。

發行區域

當 *.csproj 檔案中包含 <Project Sdk="Microsoft.NET.Sdk.Web"> 時,會將所有 *.cshtml 檔案及 wwwroot 目錄內的檔案發佈至輸出。

使用 Visual Studio 新增 MVC 區域

在方案總管中,以滑鼠右鍵按一下專案,然後選取 [新增 > Scaffolded 專案],然後選取[MVC 區域]。

區域是 ASP.NET 功能,可用來將相關功能組織為群組,以作為個別的命名空間 (適用於路由) 和資料夾結構 (適用於檢視)。 使用區域會藉由將另一個路由參數 、 area 和 或 Page page 新增至 controlleractionRazor ,以建立階層以進行路由。

區域提供一種方式,將 ASP.NET Core Web 應用程式分割成較小的功能群組,每個群組都有自己的一組 Razor 頁面、控制器、檢視和模型。 一個區域基本上是應用程式內的一個結構。 在 ASP.NET Core Web 專案中,Pages、模型、控制器和檢視等邏輯元件都會保留在不同的資料夾中。 ASP.NET Core 執行階段會使用命名慣例來建立這些元件之間的關聯性。 針對大型應用程式,將應用程式分割成個別高功能層級區域可能較有利。 舉例來說,一個電子商務應用程式可具有多個業務單位,例如結帳、計費和搜尋。 每個單位都有自己的區域,可包含檢視、控制器、 Razor 頁面和模型。

處於下列情況時,請考慮在專案中使用區域:

  • 應用程式是由可以邏輯方式區隔的多個高階功能性元件所組成的。
  • 您想要分割應用程式,讓每個功能區域都可獨立運作。

檢視或下載範例程式碼 (如何下載)。 下載範例提供基本的應用程式來測試區域。

如果您使用 Razor Pages,請參閱本檔中 具有 Razor 頁面的區域

適用於控制器與檢視的區域

使用區域、控制器及檢視的典型 ASP.NET Core Web 應用程式包含下列項目:

  • 一個區域資料夾結構

  • 控制器具有 屬性, [Area] 可將控制器與區域產生關聯:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • 新增至啟動的區域路由

    app.UseMvc(routes =>
    {
        routes.MapRoute(
          name: "MyArea",
          template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    
        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
    

區域資料夾結構

假設應用程式具有兩個邏輯群組:「產品」和「服務」。 使用區域,資料夾結構應該如下:

  • 專案名稱
    • 區域
      • 產品
        • 控制器
          • HomeController.cs
          • ManageController.cs
        • 檢視
          • Home
            • Index.cshtml
          • 管理
            • Index.cshtml
            • About.cshtml
      • 服務
        • 控制器
          • HomeController.cs
        • 檢視
          • Home
            • Index.cshtml

儘管上述配置通常會在使用區域時使用,但是只需有檢視檔案,就能使用此資料夾結構。 檢視探索會依下列順序搜尋相符的區域檢視檔案:

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

使控制器與區域產生關聯

區網域控制站是使用 [Area] 屬性來指定:

using Microsoft.AspNetCore.Mvc;

namespace MVCareas.Areas.Products.Controllers
{
    [Area("Products")]
    public class ManageController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult About()
        {
            return View();
        }
    }
}

新增區域路由

區域路由通常會使用慣例路由,而非屬性路由。 慣例路由與順序息息相關。 一般而言,具有區域的路由應該放在路由表前面,因為這些路由比沒有區域的路由更明確。

如果 URL 空間在所有區域中都是統一的,則可使用 {area:...} 作為路由範本中的語彙基元:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
          name: "MyArea",
          template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
}

在上述程式碼中,exists 會套用路由必須與區域相符的條件約束。 若要將路由新增至區域,使用 {area:...} 是最簡單的機制。

下列程式碼會使用 MapAreaRoute 來建立兩個具名的區域路由:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapAreaRoute(
            name: "MyAreaProducts",
            areaName:"Products",
            template: "Products/{controller=Home}/{action=Index}/{id?}");

        routes.MapAreaRoute(
            name: "MyAreaServices",
            areaName: "Services",
            template: "Services/{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
}

搭配 ASP.NET Core 2.2 使用 MapAreaRoute 時,請參閱這個 GitHub 問題 \(英文\)。

如需詳細資訊,請參閱區域路由

以下來自範例下載的程式碼會顯示使用指定的區域來產生連結:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage", 
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

使用上述程式碼產生的連結,在應用程式中的任何位置都是有效的。

範例下載包括部分檢視,其中可在未指定區域的情況下包含上述連結和相同連結。 部分檢視會在配置檔案中進行參考,因此,應用程式中的每個頁面都會顯示產生的連結。 在未指定區域的情況下產生的連結,只有在從相同區域與控制器中的頁面進行參考時才有效。

未指定區域或控制站時,路由即會取決於「環境」值。 目前要求的目前路由值被視為用於連結產生的環境值。 在許多適用於範例應用程式的案例中,使用環境值會產生不正確的連結。

如需詳細資訊,請參閱路由至控制器動作

使用 _ViewStart.cshtml 檔案共用區域的配置

若要共用整個應用程式的通用配置,請將 移至 _ViewStart.cshtml 應用程式根資料夾。

_ViewImports.cshtml

在其標準位置中, /Views/_ViewImports.cshtml 不適用於區域。 若要在區域中使用常見的 標籤協助程式@using@inject ,請確定適當的 _ViewImports.cshtml 檔案 適用于您的區域檢視。 如果您想要所有檢視中的相同行為,請移至 /Views/_ViewImports.cshtml 應用程式根目錄。

變更檢視儲存所在的預設區域資料夾

下列程式碼會將預設的區域資料夾從 "Areas" 變更為 "MyAreas"

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.AreaViewLocationFormats.Clear();
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
    });

    services.AddMvc();
}

具有 Razor 頁面的區域

具有 Razor Pages 的區域需要 Areas/<area name>/Pages 應用程式根目錄中的資料夾。 下列資料夾結構搭配範例應用程式一起使用:

  • 專案名稱
    • 區域
      • 產品
        • 頁面
          • _ViewImports
          • 關於
          • 索引
      • 服務
        • 頁面
          • 管理
            • 關於
            • 索引

以下來自範例下載的程式碼會顯示使用指定的區域 (例如 asp-area="Products") 來產生連結:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

使用上述程式碼產生的連結,在應用程式中的任何位置都是有效的。

範例下載包括部分檢視,其中可在未指定區域的情況下包含上述連結和相同連結。 部分檢視會在配置檔案中進行參考,因此,應用程式中的每個頁面都會顯示產生的連結。 在未指定區域的情況下產生的連結,只有在從相同區域中的頁面進行參考時才有效。

未指定區域時,路由即會取決於「環境」值。 目前要求的目前路由值被視為用於連結產生的環境值。 在許多適用於範例應用程式的案例中,使用環境值會產生不正確的連結。 例如,試想從下列程式碼產生的連結:

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

針對上述程式碼:

  • 僅當最後一個要求是針對 Services 區域中的頁面時,從 <a asp-page="/Manage/About"> 產生的連結才是正確的。 例如,/Services/Manage//Services/Manage/Index/Services/Manage/About
  • 僅當最後一個要求是針對 /Home 中的頁面時,從 <a asp-page="/About"> 產生的連結才是正確的。
  • 程式碼來自下載範例

使用 _ViewImports 檔案匯入命名空間和標記協助程式

您可以將檔案 _ViewImports.cshtml 新增至每個區域 Pages 資料夾,以將命名空間和標籤協助程式匯入資料夾中的每一 Razor 個頁面。

請考慮範例程式碼 的服務區域, 其中不包含檔案 _ViewImports.cshtml 。 下列標記顯示/Services/Manage/AboutRazor Page:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<h2>/Services/Manage/About</h2>

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

在上述標記中:

  • 必須使用完整的網域名稱來指定此模型 (@model RPareas.Areas.Services.Pages.Manage.AboutModel)。
  • 標記協助程式@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 啟用

在範例下載中,Products 區域包含下列 _ViewImports.cshtml 檔案:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

下列標記顯示/Products/AboutRazor Page:

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

<h2>Products/About</h2>

<a asp-area="Services" asp-page="/Manage/About">
    Services/Manage/About
</a>

在上述檔案中,命名空間和 @addTagHelper 指示詞會由 Areas/Products/Pages/_ViewImports.cshtml 檔案匯入檔案。

如需詳細資訊,請參閱管理標籤協助程式範圍匯入共用指示詞

頁面區域的 Razor 共用版面配置

若要共用整個應用程式的通用配置,請將 移至 _ViewStart.cshtml 應用程式根資料夾。

發行區域

當 *.csproj 檔案中包含 <Project Sdk="Microsoft.NET.Sdk.Web"> 時,會將所有 *.cshtml 檔案及 wwwroot 目錄內的檔案發佈至輸出。