原文:Overview of ASP.NET Core MVC
作者:Steve Smith
翻譯:張海龍(jiechen)
校對:高嵩
ASP.NET Core MVC 是使用模型-視圖-控制器(Model-View-Controller)設計模式構建網頁應用與 API 的豐富的框架。
什么是 MVC 模式?
模型-視圖-控制器(MVC)架構模式將一個應用區分為三部分主要組件:模型、視圖、與控制器。這種模式有助實現關注分離。使用這種模式,用戶請求被路由到控制器,控制器負責與模型(Model)協作以執行用戶操作和/或返回請求結果。控制器(Controller)選擇視圖(View),展示給用戶,而給視圖提供其所需要的任何模型(Model)。
下面的圖表展示了這三個主要組件以及它們間的相互引用:
這個職責示意圖幫你掌控你的應用的復雜程度,因為其更容易編碼、調試、與測試一些(模型、視圖、控制器)有單一功能的模塊 (進一步了解單一職責原則)。存在兩者或者此三者之間的廣泛依賴是非常難更新、測試、調試代碼的。例如,用戶界面邏輯與業務邏輯相比傾向於變化更頻繁。如果表現代碼與業務邏輯混雜在一個對象內,在你每次改變用戶界面的時候都需要修改一個包含業務邏輯的對象。這也就更容易引入錯誤,並使得你在每次做一個很小的用戶界面改動后都要進行完整的業務邏輯測試。
視圖與控制器都依賴於模型。盡管如此,模型並不依賴於視圖,也不依賴於控制器。這是分離的一大優勢。這樣分離允許不依賴於視覺表現創建並測試模型。
模型(Model)職責
MVC 應用中的模型代表了應用的狀態和業務邏輯或其可以展現的一些操作。業務邏輯應該封裝在模型,連同應用持久化狀態實現邏輯。強類型視圖一般使用特別設計的視圖模型(ViewModel)類型,它包含了視圖顯示需要的數據;控制器將創建並從模型填充這些視圖模型。
有許多種方法組織 MVC 架構形式的應用中的模型。了解更多關於 不同類型的模型。
視圖(View)職責
視圖負責在用戶界面呈現內容。它們使用 Razor 視圖引擎在 HTML 標記中嵌入 .NET 代碼。視圖中應僅包含少量的邏輯,而這些邏輯應該是與呈現內容相關的。如果你發現需要在視圖文件中完成大量的邏輯任務,以便從復雜的模型展示數據,請考慮使用視圖組件視圖模型、或視圖模板來簡化視圖。
控制器(Controller)職責
控制器是承載用戶交互、模型運轉、並最終選擇視圖進行渲染的組件。在 MVC 應用中,視圖只顯示信息;控制器處理並對用戶輸入和交互做出響應。在 MVC 模式,控制器是最初的入口,負責選擇同哪一個模型類型協作和選擇哪一個視圖用來呈現(就如其名:它控制應用對所給的請求如何做出響應)。
控制器不應該有太多職責而過於復雜。 為避免控制器邏輯過於復雜,請使用單一職責原則將業務邏輯從控制器移到領域模型。
什么是 ASP.NET Core MVC
ASP.NET Core MVC 框架是一個為使用 ASP.NET Core 優化的輕量級、開源、高度可測試的表現框架。
ASP.NET Core MVC 提供了一種基於模式的、使用干凈的關注分離的方式構建動態網站。它使你能對標簽完全控制,支持友好的測試驅動開發(TDD)開發方式並且使用最新的 Web 標准。
功能特點
ASP.NET Core MVC 包括以下特點:
- 路由
- 模型綁定
- 模型驗證
- 依賴注入
- 過濾器
- 區域
- 網絡應用程序接口
- 可測試性
- Razor視圖引擎
- 強類型視圖
- 標簽輔助類
- 視圖組件
路由
ASP.NET Core MVC 是建立在ASP.NET Core 路由上的,一項強大的 URL 映射組件,助你建立擁有可理解的、可搜索的 URL 的應用。這使得你可以定義你的應用的 URL 命名形式,使得它對搜索引擎優化(SEO)和鏈接生成中運行良好,而不用關心你的 WEB 服務器上的文件如何組織。你可以使用方便的路由模板語法定義你的路由,路由模板語法支持路由值約束、默認值和可選值。
基於約束的路由 允許你全局定義你的應用支持的 URL 格式,及這些格式如何各自在給定的控制器中映射到指定的操作(Action)方法。 當接收到傳入請求,路由引擎轉換 URL 且匹配它至一個定義的 URL 格式模板,然后調用關聯的控制器的操作方法。
routes.MapRoute(name: "Default", template: "{controller=Home}/{action=Index}/{id?}");
特性路由(Attribute routing) 允許你以在控制器和方法使用添加特性的方式指定路由信息來定義你的應用的路由。這意味着你的路由定義緊鄰它們所關聯的控制器和方法。
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
...
}
}
模型(Model)綁定
ASP.NET Core MVC 模型綁定轉換客戶端請求數據(從值、路由數據、請求字符參數、HTTP 標頭)為控制器可以處理的對象。所以,你的控制器邏輯不需要做識別傳入請求數據的工作;使得參數數據傳入到操作方法簡單化。
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { ... }
模型(Model)驗證
ASP.NET Core MVC 支持 校驗,通過為你的模型對象添加數據批注校驗特性裝飾。校驗特性在客戶端數值傳到服務器之前被檢查,同時在控制器方法被調用之前也會檢查。
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; }
}
一個控制器方法:
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
// work with the model
}
// If we got this far, something failed, redisplay form
return View(model);
}
框架在客戶端和服務端都將處理請求數據校驗。在模型上指定的驗證邏輯被添加到渲染后的視圖中作為隱藏腳本,且利用 jQuery Validation在瀏覽器中被強制執行。
依賴注入
ASP.NET Core 內置了對 依賴注入 (DI)的支持。在 ASP.NET Core MVC 中 控制器 能通過它們的構造函數請求所需的服務,允許它們遵循 顯式依賴項原則。
你的應用也可以使用 視圖文件中的依賴注入,使用 @inject
命令:
@inject SomeService ServiceName
<!DOCTYPE html>
<html>
<head>
<title>@ServiceName.GetTitle</title>
</head>
<body>
<h1>@ServiceName.GetTitle</h1>
</body>
</html>
過濾器(Filters)
過濾器幫助開發者封裝橫切關注點,如異常處理或身份驗證。過濾器允許運行為操作方法自定義的前期的和請求過程中的邏輯,也可以被配置為在給定請求的執行管道的特定時刻執行。過濾器可以作為特性被應用到控制器或方法(也可以全局運行)。框架包含了幾項過濾器(比如 Authorize
)。
[Authorize]
public class AccountController : Controller
{
區域(Areas)
Areas提供了一種將龐大的 ASP.NET Core MVC 網站應用分解的方法。區域是應用中一項有效的MVC結構。在 MVC 項目中,邏輯組件如 Model、控制器及視圖放在不同的文件夾,MVC 使用命名規范來在這些組件間建立關系。對龐大的應用,將應用分解為單獨的高級功能區域是非常有益的。例如,一個電子商務應用擁有多個業務單元,比如結算、賬單、與搜索等。這些單元中的每一項都有它們各自的邏輯組件視圖、控制器和模型。
網絡應用程序接口(Web APIs)
除了是一個強大的創建網站的平台,ASP.NET Core MVC 對 Web APIs 也具有強有力的支持。你可以創建服務,連接到廣泛的客戶端,包括各種瀏覽器和移動設備。
框架內置支持格式化數據如 JSON 或 XML ,使其具備了對 HTTP 內容協商的支持。編寫自定義格式以支持你的自有格式。
使用鏈接生成可以啟用對超媒體的支持。簡單地啟用對跨域資源共享 (CORS)的支持,可使得你的 Web APIs 能在多個應用間共享。
可測試性(Testablility)
框架接口和依賴注入的使用,使其適合進行單元測試,且框架包含的功能(如 TestHost 和 Entity Framework 內存提供程序)使得集成測試也是非常快捷和方便的。了解更多關於測試控制器邏輯。
Razor 視圖引擎
ASP.NET Core MVC 視圖使用Razor 視圖引擎渲染視圖。 Razor 是一種緊湊的、表達能力好且流暢的模板標記語言,用來使用嵌入的 C# 代碼定義視圖。Razor 被用來在服務器動態生成 Web 內容。你可以清晰地將服務端代碼和客戶端代碼跟內容混合在一起。
<ul>
@for (int i = 0; i < 5; i++) {
<li>List item @i</li>
}
</ul>
使用 Razor 視圖引擎你可以定義布局模板,局部視圖及可替換的區塊。
強類型視圖
MVC 中的 Razor 視圖可以強類型於你的模型。控制器可以傳遞強類型模型到視圖,使你的視圖支持類型檢查和智能提示。
例如,下面的視圖定義了 IEnumerable<Product>
類型的模型:
@model IEnumerable<Product>
<ul>
@foreach (Product p in Model)
{
<li>@p.Name</li>
}
</ul>
標簽輔助類(Tag Helper)
Tag Helpers使得服務端代碼可以在 Razor 文件中參與創建和渲染 HTML 元素。你可以使用 tag helper 定義自己的標簽(比如 <environment>
)或更改已知標簽的行為(如 <label>
)。 Tag Helper 依據元素名稱和屬性綁定到指定元素。它們為服務端渲染帶來便利的同時保留了 HTML 編輯體驗。
有很多內置的 Tag Helper 應對常用任務,比如創建表單、鏈接、加載資源等,並且在公共的 GitHub 倉庫或作為 NuGet 包,還有更多可用的。Tag Helper 是用 C# 創作的,它們通過元素名、屬性名或父標簽定位 HTML 元素。例如,內置的 LinkTagHelper 可被用來創建一個鏈接指向到 AccountsController
的 Login
方法:
<p>
Thank you for confirming your email.
Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>.
</p>
EnvironmentTagHelper
可以用來在運行時環境包含不同的腳本到你的視圖(例如:原始的或壓縮的),例如 Development, Staring, 或 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.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery">
</script>
</environment>
Tag Helper 提供友好的 HTML 開發體驗和創建 HTML 與 Razor 標記時的豐富的智能提示。大多數內置的 Tag Helper 指向存在的 HTML 元素並且為元素提供服務端屬性。
視圖組件
View Components允許你打包渲染邏輯並在應用中重用它。它們與局部視圖類似,但具有相關的邏輯。