Nguon: Microsoft Learn · .NET 8.0

Areas trong ASP.NET Core

Nguồn: Areas in ASP.NET Core

Bởi Dhananjay KumarRick Anderson

Areas (khu vực) là một tính năng ASP.NET được sử dụng để tổ chức chức năng liên quan thành một nhóm riêng biệt:

Sử dụng areas tạo ra một hệ thống phân cấp cho mục đích routing bằng cách thêm một tham số route khác, area, vào controlleraction hoặc page của Razor Page.

Areas cung cấp một cách để phân chia một ứng dụng Web ASP.NET Core thành các nhóm chức năng nhỏ hơn, mỗi nhóm có tập Razor Pages, controllers, views và models riêng của mình. Một area thực chất là một cấu trúc bên trong ứng dụng. Trong một dự án web ASP.NET Core, các thành phần logic như Pages, Model, Controller và View được lưu trong các thư mục khác nhau. ASP.NET Core runtime sử dụng các naming conventions (quy ước đặt tên) để tạo ra mối quan hệ giữa các thành phần này. Đối với ứng dụng lớn, có thể có lợi khi phân chia ứng dụng thành các khu vực chức năng cấp cao riêng biệt. Ví dụ, một ứng dụng thương mại điện tử với nhiều đơn vị kinh doanh, chẳng hạn như checkout (thanh toán), billing (hóa đơn) và search (tìm kiếm). Mỗi đơn vị này có area riêng để chứa views, controllers, Razor Pages và models.

Hãy cân nhắc sử dụng Areas trong một dự án khi:

Areas cho controllers với views

Một ứng dụng web ASP.NET Core điển hình sử dụng areas, controllers và views chứa những điều sau:

``csharp [Area("Products")] public class ManageController : Controller { ``

```csharp 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(); ```

Cấu trúc thư mục Area

Hãy xem xét một ứng dụng có hai nhóm logic, ProductsServices. Sử dụng areas, cấu trúc thư mục sẽ tương tự như sau:

Mặc dù layout trên là điển hình khi sử dụng Areas, chỉ có các tệp view mới được yêu cầu sử dụng cấu trúc thư mục này. View discovery (tìm kiếm view) tìm kiếm một tệp area view phù hợp theo thứ tự sau:

text
/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

Liên kết controller với một Area

Các area controllers được chỉ định với attribute [Area]:

csharp
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();
    }
}

Thêm Area route

Area routes thường sử dụng conventional routing (định tuyến quy ước) thay vì attribute routing (định tuyến attribute). Conventional routing phụ thuộc vào thứ tự. Nói chung, các routes với areas nên được đặt sớm hơn trong route table vì chúng cụ thể hơn các routes không có area.

{area:...} có thể được sử dụng như một token trong route templates nếu không gian URL đồng nhất trên tất cả areas:

csharp
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();

Trong code trên, exists áp dụng một constraint (ràng buộc) rằng route phải khớp với một area. Sử dụng {area:...} với MapControllerRoute:

Code sau sử dụng MapAreaControllerRoute để tạo hai named area routes:

csharp
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();

Để biết thêm thông tin, xem Area routing.

Tạo liên kết với MVC areas

Code sau từ mẫu tải xuống cho thấy tạo liên kết với area được chỉ định:

cshtml
<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>

Khi area hoặc controller không được chỉ định, routing phụ thuộc vào các giá trị ambient (xung quanh). Các giá trị route hiện tại của request hiện tại được coi là các giá trị ambient cho việc tạo liên kết.

Layout chia sẻ cho Areas sử dụng tệp _ViewStart.cshtml

Để chia sẻ một layout chung cho toàn bộ ứng dụng, hãy giữ _ViewStart.cshtml trong thư mục gốc của ứng dụng.

Thư mục gốc của ứng dụng

Thư mục gốc của ứng dụng là thư mục chứa tệp Program.cs trong một ứng dụng web được tạo với các template ASP.NET Core.

_ViewImports.cshtml

/Views/_ViewImports.cshtml, cho MVC, và /Pages/_ViewImports.cshtml cho Razor Pages, không được nhập vào các views trong areas. Sử dụng một trong các cách tiếp cận sau để cung cấp view imports cho tất cả views:

Tệp _ViewImports.cshtml thường chứa các lệnh nhập Tag Helpers, @using@inject.

Thay đổi thư mục area mặc định nơi lưu trữ views

Code sau thay đổi thư mục area mặc định từ "Areas" thành "MyAreas":

csharp
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();

// ...

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

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

app.Run();

Areas với Razor Pages

Areas với Razor Pages yêu cầu một thư mục Areas/<area name>/Pages trong thư mục gốc của ứng dụng. Cấu trúc thư mục sau được sử dụng với ứng dụng mẫu:

Tạo liên kết với Razor Pages và areas

Code sau từ mẫu tải xuống cho thấy tạo liên kết với area được chỉ định (ví dụ, asp-area="Products"):

cshtml
<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>

Khi area không được chỉ định, routing phụ thuộc vào các giá trị ambient. Các giá trị route hiện tại của request hiện tại được coi là các giá trị ambient cho việc tạo liên kết. Trong nhiều trường hợp cho ứng dụng mẫu, sử dụng các giá trị ambient tạo ra các liên kết không chính xác.

Nhập namespace và Tag Helpers với tệp _ViewImports

Một tệp _ViewImports.cshtml có thể được thêm vào mỗi thư mục area Pages để nhập namespace và Tag Helpers cho mỗi Razor Page trong thư mục.

Hãy xem xét area Services của code mẫu, không chứa tệp _ViewImports.cshtml. Markup sau hiển thị Razor Page /Services/Manage/About:

cshtml
@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>

Trong markup trên:

Trong mẫu tải xuống, area Products chứa tệp _ViewImports.cshtml sau:

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

Markup sau hiển thị Razor Page /Products/About:

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

Trong tệp trên, namespace và chỉ thị @addTagHelper được nhập vào tệp bởi tệp Areas/Products/Pages/_ViewImports.cshtml.

Layout chia sẻ cho Razor Pages Areas

Để chia sẻ một layout chung cho toàn bộ ứng dụng, hãy di chuyển _ViewStart.cshtml đến thư mục gốc của ứng dụng.

Xuất bản Areas

Tất cả các tệp *.cshtml và các tệp trong thư mục wwwroot được xuất bản ra output khi <Project Sdk="Microsoft.NET.Sdk.Web"> được bao gồm trong tệp *.csproj.

Thêm MVC Area với Visual Studio

Trong Solution Explorer, nhấp chuột phải vào dự án và chọn ADD > New Scaffolded Item, sau đó chọn MVC Area.