Tổng quan về ASP.NET Core MVC
Nguồn: Overview of ASP.NET Core MVC
Tác giả: Steve Smith
ASP.NET Core MVC là một framework (khung làm việc) phong phú để xây dựng web app và API sử dụng mẫu thiết kế Model-View-Controller.
Mẫu MVC (MVC pattern)
Mẫu kiến trúc Model-View-Controller (MVC) tách ứng dụng thành ba nhóm component chính: Models (mô hình), Views (giao diện) và Controllers (bộ điều khiển). Mẫu này giúp đạt được separation of concerns (phân tách mối quan tâm). Khi sử dụng mẫu này, request của người dùng được định tuyến đến Controller, có trách nhiệm làm việc với Model để thực hiện các hành động của người dùng và/hoặc truy xuất kết quả truy vấn. Controller chọn View để hiển thị cho người dùng và cung cấp cho nó bất kỳ dữ liệu Model nào cần thiết.
Sơ đồ sau cho thấy ba component chính và những component nào tham chiếu đến các component khác:
[User Request] → Controller → Model
↓ ↑
View ────────┘Sự phân chia trách nhiệm này giúp bạn mở rộng ứng dụng về mặt độ phức tạp vì dễ dàng hơn để code, debug và test một thứ (model, view hoặc controller) chỉ có một công việc duy nhất. Việc cập nhật, test và debug code có phụ thuộc trải rộng trên hai hoặc nhiều hơn ba khu vực này sẽ khó khăn hơn.
Cả view và controller đều phụ thuộc vào model. Tuy nhiên, model không phụ thuộc vào view hay controller. Đây là một trong những lợi ích chính của sự phân tách này. Sự phân tách này cho phép model được xây dựng và test độc lập với trình bày trực quan.
Trách nhiệm của Model
Model trong ứng dụng MVC đại diện cho trạng thái của ứng dụng và bất kỳ logic nghiệp vụ hoặc các thao tác nào cần được thực hiện bởi nó. Logic nghiệp vụ nên được đóng gói trong model, cùng với bất kỳ logic triển khai nào để lưu trữ trạng thái của ứng dụng. Strongly-typed view (view kiểu mạnh) thường sử dụng kiểu ViewModel được thiết kế để chứa dữ liệu hiển thị trên view đó. Controller tạo và điền vào các instance ViewModel này từ model.
Trách nhiệm của View
View chịu trách nhiệm trình bày nội dung thông qua giao diện người dùng. Chúng sử dụng Razor view engine để nhúng code .NET vào markup HTML. Nên có ít logic tối thiểu trong view, và bất kỳ logic nào trong chúng nên liên quan đến việc trình bày nội dung. Nếu bạn thấy cần phải thực hiện nhiều logic trong các file view để hiển thị dữ liệu từ model phức tạp, hãy xem xét sử dụng View Component (thành phần view), ViewModel hoặc view template (mẫu view) để đơn giản hóa view.
Trách nhiệm của Controller
Controller là các component xử lý tương tác của người dùng, làm việc với model và cuối cùng chọn view để render. Trong ứng dụng MVC, view chỉ hiển thị thông tin; controller xử lý và phản hồi đầu vào và tương tác của người dùng. Trong mẫu MVC, controller là điểm vào ban đầu và có trách nhiệm chọn loại model nào để làm việc và view nào để render.
Controller không nên quá phức tạp với quá nhiều trách nhiệm. Để giữ logic controller không trở nên quá phức tạp, hãy đẩy logic nghiệp vụ ra khỏi controller và vào domain model (mô hình miền).
Gợi ý: Nếu bạn thấy rằng các controller action thường xuyên thực hiện cùng loại hành động, hãy chuyển những hành động chung này vào filter (bộ lọc).
ASP.NET Core MVC
Framework ASP.NET Core MVC là một presentation framework (framework trình bày) nhẹ, mã nguồn mở, có khả năng kiểm thử cao, được tối ưu hóa để sử dụng với ASP.NET Core.
ASP.NET Core MVC cung cấp một cách dựa trên pattern để xây dựng các website động cho phép phân tách mối quan tâm rõ ràng. Nó cho bạn toàn quyền kiểm soát markup, hỗ trợ phát triển TDD-friendly và sử dụng các web standard mới nhất.
Routing (Định tuyến)
ASP.NET Core MVC được xây dựng trên ASP.NET Core's routing, một component ánh xạ URL mạnh mẽ cho phép bạn xây dựng các ứng dụng có URL dễ hiểu và có thể tìm kiếm được. Điều này cho phép bạn định nghĩa các mẫu đặt tên URL cho ứng dụng hoạt động tốt cho tối ưu hóa công cụ tìm kiếm (SEO) và tạo link, mà không phụ thuộc vào cách các file trên web server của bạn được tổ chức. Bạn có thể định nghĩa route của mình bằng cú pháp route template tiện lợi hỗ trợ các ràng buộc giá trị route, giá trị mặc định và tùy chọn.
Convention-based routing (định tuyến dựa trên quy ước) cho phép bạn định nghĩa toàn cục các định dạng URL mà ứng dụng chấp nhận và cách mỗi định dạng đó ánh xạ đến một action method cụ thể trên một controller nhất định. Khi nhận được request đến, routing engine phân tích URL và khớp nó với một trong các định dạng URL đã được định nghĩa, sau đó gọi action method của controller liên quan.
routes.MapRoute(name: "Default", template: "{controller=Home}/{action=Index}/{id?}");Attribute routing (định tuyến thuộc tính) cho phép bạn chỉ định thông tin routing bằng cách trang trí controller và action của bạn với các attribute (thuộc tính) định nghĩa route của ứng dụng. Điều này có nghĩa là định nghĩa route của bạn được đặt gần controller và action mà chúng liên kết.
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
...
}
}Model binding (Ràng buộc model)
ASP.NET Core MVC model binding chuyển đổi dữ liệu request của client (giá trị form, route data, tham số query string, HTTP header) thành các đối tượng mà controller có thể xử lý. Kết quả là, logic controller của bạn không phải thực hiện công việc tìm ra dữ liệu request đến; nó chỉ đơn giản có dữ liệu dưới dạng các tham số của action method.
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { ... }Model validation (Xác thực model)
ASP.NET Core MVC hỗ trợ validation (xác thực) bằng cách trang trí đối tượng model của bạn với các data annotation validation attribute. Validation attribute được kiểm tra ở phía client trước khi các giá trị được post lên server, cũng như trên server trước khi controller action được gọi.
using System.ComponentModel.DataAnnotations;
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}Một controller action:
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
// làm việc với model
}
// Tại điểm này, có gì đó thất bại, hiển thị lại form
return View(model);
}Framework xử lý việc xác thực dữ liệu request cả ở phía client và server. Logic xác thực được chỉ định trên các kiểu model được thêm vào các view đã render dưới dạng annotation không rõ ràng và được thực thi trong trình duyệt với jQuery Validation.
Dependency injection (Tiêm phụ thuộc)
ASP.NET Core có hỗ trợ tích hợp cho dependency injection (DI). Trong ASP.NET Core MVC, controller có thể yêu cầu các service cần thiết thông qua constructor của chúng, cho phép chúng tuân theo Explicit Dependencies Principle (Nguyên tắc phụ thuộc rõ ràng).
Ứng dụng của bạn cũng có thể sử dụng dependency injection trong file view, sử dụng directive @inject:
@inject SomeService ServiceName
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ServiceName.GetTitle</title>
</head>
<body>
<h1>@ServiceName.GetTitle</h1>
</body>
</html>Filters (Bộ lọc)
Filter giúp developer đóng gói các mối quan tâm xuyên suốt (cross-cutting concerns), như xử lý ngoại lệ hoặc authorization. Filter cho phép chạy logic tiền xử lý và hậu xử lý tùy chỉnh cho action method và có thể được cấu hình để chạy tại các điểm nhất định trong execution pipeline cho một request nhất định. Filter có thể được áp dụng cho controller hoặc action dưới dạng attribute (hoặc có thể chạy toàn cục). Một số filter (chẳng hạn như Authorize) được bao gồm trong framework. [Authorize] là attribute được sử dụng để tạo MVC authorization filter.
[Authorize] public class AccountController : Controller
Areas (Khu vực)
Area cung cấp một cách để phân vùng ứng dụng web ASP.NET Core MVC lớn thành các nhóm chức năng nhỏ hơn. Một area là một cấu trúc MVC bên trong ứng dụng. Trong dự án MVC, các component logic như Model, Controller và View được giữ trong các thư mục khác nhau và MVC sử dụng naming convention để tạo mối quan hệ giữa các component này. Đối với ứng dụng lớn, có thể có lợi khi phân vùng ứng dụng thành các khu vực chức năng cấp cao riêng biệt.
Web APIs (API web)
Ngoài việc là một nền tảng tuyệt vời để xây dựng website, ASP.NET Core MVC có hỗ trợ tốt để xây dựng Web API. Bạn có thể xây dựng các service tiếp cận nhiều loại client khác nhau bao gồm trình duyệt và thiết bị di động.
Framework bao gồm hỗ trợ content-negotiation HTTP với hỗ trợ tích hợp để định dạng dữ liệu dưới dạng JSON hoặc XML. Viết custom formatter để thêm hỗ trợ cho các định dạng của riêng bạn.
Sử dụng link generation (tạo link) để bật hỗ trợ cho hypermedia. Dễ dàng bật hỗ trợ Cross-Origin Resource Sharing (CORS) để Web API của bạn có thể được chia sẻ trên nhiều ứng dụng web.
Testability (Khả năng kiểm thử)
Việc sử dụng các interface và dependency injection của framework làm cho nó phù hợp với unit test, và framework bao gồm các tính năng (như TestHost và InMemory provider cho Entity Framework) làm cho integration test nhanh chóng và dễ dàng.
Razor view engine
ASP.NET Core MVC view sử dụng Razor view engine để render view. Razor là ngôn ngữ template markup compact, biểu đạt và linh hoạt để định nghĩa view sử dụng code C# nhúng. Razor được sử dụng để tạo nội dung web động trên server. Bạn có thể kết hợp rõ ràng server code với nội dung và code phía client.
<ul>
@for (int i = 0; i < 5; i++) {
<li>List item @i</li>
}
</ul>Sử dụng Razor view engine bạn có thể định nghĩa layout, partial view và các section có thể thay thế.
Strongly typed views (View kiểu mạnh)
Razor view trong MVC có thể được typed mạnh dựa trên model của bạn. Controller có thể truyền một model kiểu mạnh cho view cho phép view của bạn có kiểm tra kiểu và hỗ trợ IntelliSense.
Ví dụ, view sau render một model kiểu IEnumerable<Product>:
@model IEnumerable<Product>
<ul>
@foreach (Product p in Model)
{
<li>@p.Name</li>
}
</ul>Tag Helpers (Trợ lý thẻ)
Tag Helper cho phép server side code tham gia vào việc tạo và render các phần tử HTML trong các file Razor. Bạn có thể sử dụng tag helper để định nghĩa các thẻ tùy chỉnh (ví dụ: <environment>) hoặc để thay đổi hành vi của các thẻ hiện có (ví dụ: <label>). Tag Helper ràng buộc với các phần tử cụ thể dựa trên tên phần tử và các attribute của nó. Chúng cung cấp lợi ích của server-side rendering trong khi vẫn giữ trải nghiệm chỉnh sửa HTML.
Có nhiều Tag Helper tích hợp sẵn cho các tác vụ phổ biến - như tạo form, link, tải tài nguyên và nhiều hơn nữa. Ví dụ, LinkTagHelper tích hợp có thể được sử dụng để tạo link đến action Login của AccountsController:
<p>
Thank you for confirming your email.
Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>.
</p>EnvironmentTagHelper có thể được sử dụng để bao gồm các script khác nhau trong view của bạn (ví dụ: raw hoặc minified) dựa trên môi trường runtime, như Development, Staging hoặc Production:
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.js"
asp-fallback-src="~/lib/jquery/dist/jquery.js"
asp-fallback-test="window.jQuery">
</script>
</environment>View Components (Thành phần view)
View Component cho phép bạn đóng gói logic render và tái sử dụng nó trong toàn bộ ứng dụng. Chúng tương tự như partial view, nhưng có logic liên quan.