ASP.NET Core 中的區域
作者:Dhananjay Kumar和Rick Anderson
區域是 ASP.NET 功能,用來將相關功能組織成個別的群組:
- 路由的命名空間。
- 檢視和 Razor 頁面的資料夾結構。
使用區域可藉由將另一個路由參數 、 area
和 或 Page page
新增至 controller
, action
Razor 以建立階層以用於路由。
區域可讓您將 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();
區域資料夾結構
假設應用程式具有兩個邏輯群組:「產品」和「服務」。 使用區域,資料夾結構應該如下:
- 專案名稱
- 區域
- 產品
- 控制器
- 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
會套用路由必須與區域相符的條件約束。 搭配 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();
如需詳細資訊,請參閱區域路由。
使用 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 中的版面配置
應用程式根資料夾
應用程式根資料夾是資料夾,其中包含 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
- 關於
- 索引
- 頁面
- 服務
- 頁面
- 管理
- 關於
- 索引
- 管理
- 頁面
- 產品
- 區域
使用 Razor 頁面和區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域 (例如 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 區域]。
其他資源
- 檢視或下載範例程式碼 (如何下載)。 下載範例提供基本的應用程式來測試區域。
- MyDisplayRouteInfo 和 ToCtxString 是由 Rick.Docs.Samples.RouteInfo NuGet 套件提供。 方法會顯示
Controller
和Razor Page
路由資訊。
區域是 ASP.NET 功能,用來將相關功能組織成個別的群組:
- 路由的命名空間。
- 檢視和 Razor 頁面的資料夾結構。
使用區域可藉由將另一個路由參數 、 area
和 或 Page page
新增至 controller
, action
Razor 以建立階層以用於路由。
區域可讓您將 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
- 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
會套用路由必須與區域相符的條件約束。 搭配 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?}");
});
}
如需詳細資訊,請參閱區域路由。
使用 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 頁面的區域
具有 Razor Pages 的區域需要 Areas/<area name>/Pages
應用程式根目錄中的資料夾。 下列資料夾結構搭配範例應用程式一起使用:
- 專案名稱
- 區域
- 產品
- 頁面
- _ViewImports
- 關於
- 索引
- 頁面
- 服務
- 頁面
- 管理
- 關於
- 索引
- 管理
- 頁面
- 產品
- 區域
使用 Razor 頁面和區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域 (例如 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
新增至 controller
和 action
Razor ,以建立階層以進行路由。
區域提供一種方式,將 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
- 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 頁面的區域
具有 Razor Pages 的區域需要 Areas/<area name>/Pages
應用程式根目錄中的資料夾。 下列資料夾結構搭配範例應用程式一起使用:
- 專案名稱
- 區域
- 產品
- 頁面
- _ViewImports
- 關於
- 索引
- 頁面
- 服務
- 頁面
- 管理
- 關於
- 索引
- 管理
- 頁面
- 產品
- 區域
使用 Razor 頁面和區域產生連結
以下來自範例下載的程式碼會顯示使用指定的區域 (例如 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 目錄內的檔案發佈至輸出。