ASP.NET Core 中的區域
作者:Dhananjay Kumar 和 Rick Anderson
區域是一項 ASP.NET 功能,用來將相關功能組織成個別的群組以進行區隔:
- 路由的命名空間。
- 檢視和 Razor 頁面的資料夾結構。
使用區域可基於路由的目的,藉由將另一個路由參數 (area
) 新增至 controller
和 action
或是 Razor 頁面 page
來建立階層。
區域可提供一種方式來將 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 {
-
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();
區域資料夾結構
假設應用程式具有兩個邏輯群組:「產品」和「服務」。 使用區域,資料夾結構應該如下:
- Project name
- 區域
- 產品
- 控制器
- HomeController.cs
- ManageController.cs
- 檢視
- Home
- Index.cshtml
- 管理
- Index.cshtml
- About.cshtml
- Home
- 控制器
- 服務
- 控制器
- HomeController.cs
- 檢視
- Home
- Index.cshtml
- Home
- 控制器
- 產品
- 區域
儘管上述配置通常會在使用區域時使用,但是只需有檢視檔案,就能使用此資料夾結構。 檢視探索會依下列順序搜尋相符的區域檢視檔案:
/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
會套用路由必須與區域相符的條件約束。 使用 {area:...}
搭配 MapControllerRoute
:
- 若要將路由新增至區域,這是最簡單的機制。
- 使所有控制器符合
[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();
如需詳細資訊,請參閱區域路由。
使用 MVC 區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域來產生連結:
<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 應用程式中包含 Program.cs
檔案的資料夾。
_ViewImports.cshtml
/Views/_ViewImports.cshtml (MVC) 和 /Pages/_ViewImports.cshtml (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 Pages 的區域
具有 Razor Pages 的區域需要在應用程式的根目錄中建立 Areas/<area name>/Pages
資料夾。 下列資料夾結構搭配範例應用程式一起使用:
- Project name
- 區域
- 產品
- 頁面
- _ViewImports
- 關於
- 索引
- 頁面
- 服務
- 頁面
- 管理
- 關於
- 索引
- 管理
- 頁面
- 產品
- 區域
使用 Razor Pages 和區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域 (例如 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/About Razor Pages:
@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/About Razor 頁面:
@page
@model AboutModel
@{
ViewData["Title"] = "Prod About";
}
在上述檔案中,命名空間和 @addTagHelper
指示詞會由 Areas/Products/Pages/_ViewImports.cshtml 檔案匯入到檔案。
如需詳細資訊,請參閱管理標籤協助程式範圍和匯入共用指示詞。
Razor Pages 區域的共用版面配置
若要針對整個應用程式共用通用的配置,請將 _ViewStart.cshtml 移至應用程式根資料夾。
發行區域
當 *.csproj 檔案中包含 <Project Sdk="Microsoft.NET.Sdk.Web">
時,會將所有 *.cshtml 檔案及 wwwroot 目錄內的檔案發佈至輸出。
使用 Visual Studio 新增 MVC 區域
在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [新增] > [新增 Scaffolded 專案],然後選取 [MVC 區域]。
其他資源
- 檢視或下載範例程式碼 (如何下載)。 下載範例提供基本的應用程式來測試區域。
- MyDisplayRouteInfo 和 ToCtxString 是由 Rick.Docs.Samples.RouteInfo NuGet 套件提供。 方法會顯示
Controller
和Razor Page
路由資訊。
區域是一項 ASP.NET 功能,用來將相關功能組織成個別的群組以進行區隔:
- 路由的命名空間。
- 檢視和 Razor 頁面的資料夾結構。
使用區域可基於路由的目的,藉由將另一個路由參數 (area
) 新增至 controller
和 action
或是 Razor 頁面 page
來建立階層。
區域可提供一種方式來將 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?}"); });
區域資料夾結構
假設應用程式具有兩個邏輯群組:「產品」和「服務」。 使用區域,資料夾結構應該如下:
- Project name
- 區域
- 產品
- 控制器
- HomeController.cs
- ManageController.cs
- 檢視
- Home
- Index.cshtml
- 管理
- Index.cshtml
- About.cshtml
- Home
- 控制器
- 服務
- 控制器
- HomeController.cs
- 檢視
- Home
- Index.cshtml
- Home
- 控制器
- 產品
- 區域
儘管上述配置通常會在使用區域時使用,但是只需有檢視檔案,就能使用此資料夾結構。 檢視探索會依下列順序搜尋相符的區域檢視檔案:
/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
會套用路由必須與區域相符的條件約束。 使用 {area:...}
搭配 MapControllerRoute
:
- 若要將路由新增至區域,這是最簡單的機制。
- 使所有控制器符合
[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?}");
});
}
如需詳細資訊,請參閱區域路由。
使用 MVC 區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域來產生連結:
<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.cshtml
(針對 Razor 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 Pages 的區域
具有 Razor Pages 的區域需要在應用程式的根目錄中建立 Areas/<area name>/Pages
資料夾。 下列資料夾結構搭配範例應用程式一起使用:
- Project name
- 區域
- 產品
- 頁面
- _ViewImports
- 關於
- 索引
- 頁面
- 服務
- 頁面
- 管理
- 關於
- 索引
- 管理
- 頁面
- 產品
- 區域
使用 Razor Pages 和區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域 (例如 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/About Razor Pages:
@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/About Razor 頁面:
@page
@model AboutModel
@{
ViewData["Title"] = "Prod About";
}
在上述檔案中,命名空間和 @addTagHelper
指示詞會由 Areas/Products/Pages/_ViewImports.cshtml
檔案匯入到檔案。
如需詳細資訊,請參閱管理標籤協助程式範圍和匯入共用指示詞。
Razor Pages 區域的共用版面配置
若要針對整個應用程式共用通用的配置,請將 _ViewStart.cshtml
移至應用程式根資料夾。
發行區域
當 *.csproj 檔案中包含 <Project Sdk="Microsoft.NET.Sdk.Web">
時,會將所有 *.cshtml 檔案及 wwwroot 目錄內的檔案發佈至輸出。
使用 Visual Studio 新增 MVC 區域
在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [新增] > [新增 Scaffolded 專案],然後選取 [MVC 區域]。
區域是 ASP.NET 功能,可用來將相關功能組織為群組,以作為個別的命名空間 (適用於路由) 和資料夾結構 (適用於檢視)。 使用區域可基於路由的目的,藉由將另一個路由參數 (area
) 新增至 controller
和 action
或是 Razor 頁面 page
來建立階層。
區域可提供一種方式來將 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?}"); });
區域資料夾結構
假設應用程式具有兩個邏輯群組:「產品」和「服務」。 使用區域,資料夾結構應該如下:
- Project name
- 區域
- 產品
- 控制器
- HomeController.cs
- ManageController.cs
- 檢視
- Home
- Index.cshtml
- 管理
- Index.cshtml
- About.cshtml
- Home
- 控制器
- 服務
- 控制器
- HomeController.cs
- 檢視
- Home
- Index.cshtml
- Home
- 控制器
- 產品
- 區域
儘管上述配置通常會在使用區域時使用,但是只需有檢視檔案,就能使用此資料夾結構。 檢視探索會依下列順序搜尋相符的區域檢視檔案:
/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 問題 \(英文\)。
如需詳細資訊,請參閱區域路由。
使用 MVC 區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域來產生連結:
<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 Pages 的區域
具有 Razor Pages 的區域需要在應用程式的根目錄中建立 Areas/<area name>/Pages
資料夾。 下列資料夾結構搭配範例應用程式一起使用:
- Project name
- 區域
- 產品
- 頁面
- _ViewImports
- 關於
- 索引
- 頁面
- 服務
- 頁面
- 管理
- 關於
- 索引
- 管理
- 頁面
- 產品
- 區域
使用 Razor Pages 和區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域 (例如 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/About Razor Pages:
@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/About Razor 頁面:
@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 Pages 區域的共用版面配置
若要針對整個應用程式共用通用的配置,請將 _ViewStart.cshtml
移至應用程式根資料夾。
發行區域
當 *.csproj 檔案中包含 <Project Sdk="Microsoft.NET.Sdk.Web">
時,會將所有 *.cshtml 檔案及 wwwroot 目錄內的檔案發佈至輸出。