作者:Steve Smith 和 Scott Addie
控制器、動作和動作結果是開發人員使用 ASP.NET Core MVC 建置應用程式的基礎部分。
什麼是控制器?
控制器是用來定義和分組一組動作。 動作 (或「動作方法」) 是控制器上處理要求的方法。 控制器會以邏輯方式將類似動作群組在一起。 這項動作彙總允許統一套用一組通用規則 (例如路由、快取和授權)。 要求會被透過路由對應到動作。 控制器會根據每個要求進行啟動和處置。
依照慣例,控制器類別:
- 位於專案的根層級 Controllers 資料夾中。
- 繼承自
Microsoft.AspNetCore.Mvc.Controller。
控制器是至少下列其中一個條件為 true 的可具現化類別 (通常為公用):
- 類別名稱的尾碼為
Controller。 - 類別繼承自名稱尾碼為
Controller的類別。 -
[Controller]屬性會套用至該類別。
控制器類別不得具有相關聯的 [NonController] 屬性。
控制器應該遵循明確相依性準則。 有幾種方法可以實作此準則。 如果多個控制器動作需要相同的服務,請考慮使用建構函式插入來要求這些相依性。 如果只有單一動作方法需要服務,請考慮使用動作插入來要求相依性。
在Model-View-Controller模式中,控制器負責對請求的初步處理以及對模型的具現化。 一般而言,應該在模型內執行商業決策。
控制器會取用模型的處理結果(如果有的話),並返回對應的視圖及其相關聯的數據,或 API 調用結果。 深入了解 ASP.NET Core MVC 概觀和 ASP.NET Core MVC 與 Visual Studio 使用者入門。
控制器是「UI 層級」抽象概念。 其負責確保要求資料有效,並選擇應該傳回的檢視 (或 API 的結果)。 在構造良好的應用程式中,不會直接包括資料存取或商務邏輯。 相反地,控制器會將這些責任委派給相關的服務。
定義動作
控制器上的公用方法 (不包括具有 [NonAction] 屬性的項目) 就是動作。 動作上的參數會繫結至要求資料,並使用模型繫結進行驗證。 繫結模型的所有項目都會進行模型驗證。
ModelState.IsValid 屬性值指出模型繫結和驗證是否成功。
動作方法應該包含將要求對應至業務需求的邏輯。 商務關注應該一般呈現為控制器透過相依性插入存取的服務。 動作接著會將商務動作的結果對應至應用程式狀態。
操作可以回傳任何東西,但它們經常回傳一個實例IActionResult(或對於非同步方法為Task<IActionResult>),用於產生回應。 動作方法負責選擇「回應類型」。 動作結果「執行回應」。
控制器輔助方法
控制器通常繼承自 Controller,但這不是必要的。 衍生自 Controller 提供對三種類別的協助程式方法的存取:
1. 會導致空白回應主體的方法
因為回應主體缺少可描述的內容,所以未包括 Content-Type HTTP 回應標頭。
此類別內有兩種結果類型:「重新導向」和「HTTP 狀態碼」。
HTTP 狀態碼
此類型會傳回 HTTP 狀態碼。 此類型的一些協助程式方法是
BadRequest、NotFound和Ok。 例如,return BadRequest();在執行時會產生 400 狀態碼。 當方法如BadRequest、NotFound和Ok被多載時,就不再適合作為 HTTP 狀態碼回應器,因為會執行內容交涉。重新導向
此類型會返回一個動作或目的地的重新導向(使用
Redirect、LocalRedirect、RedirectToAction或RedirectToRoute)。 例如,return RedirectToAction("Complete", new {id = 123});會重新導向至Complete,並傳遞匿名物件。「重新導向」結果類型主要的不同在於新增了
LocationHTTP 回應標頭,而非像「HTTP 狀態碼」類型。
2. 方法:導致具有預先定義內容類型的非空回應主體
此類別中的大多數協助程式方法包括 ContentType 屬性,可讓您設定 Content-Type 回應標頭來描述回應本文。
檢視
此類型回傳一個視圖,使用模型來渲染 HTML。 例如,
return View(customer);會將模型傳遞至資料繫結的視圖。格式化回應
此類型會傳回 JSON 或類似的資料交換格式,以特定方式來代表物件。 例如,
return Json(customer);會將所提供的物件序列化為 JSON 格式。此類型的其他通用方法包括
File與PhysicalFile。 例如return PhysicalFile(customerFilePath, "text/xml");會傳回 PhysicalFileResult。
3. 方法生成一個經與用戶端協商的內容類型格式化的非空回應正文
此類別普遍稱為內容交涉。
內容協商會在動作傳回ObjectResult類型或非IActionResult實作的其他項目時套用。 傳回非 IActionResult 實作的動作 (例如,object) 也會傳回「格式化回應」。
此類型的一些協助程式方法包括 BadRequest、CreatedAtRoute 和 Ok。 這些方法的範例分別包括 return BadRequest(modelState);、return CreatedAtRoute("routename", values, newobject); 和 return Ok(value);。 請注意,只有在傳遞值時,BadRequest 和 Ok 才會執行內容交涉;如果未傳遞值,則會改成作為「HTTP 狀態碼」結果類型。 相反地,CreatedAtRoute 方法一律會執行內容協商,因為其所有的重載方法都需要傳遞一個值。
跨領域關注
應用程式通常會共用其工作流程的各部分。 範例包括需要驗證購物車存取權的應用程式,或快取某些頁面上資料的應用程式。 若要在動作方法之前或之後執行邏輯,請使用 filter。 在交叉關注上使用篩選可減少重複。
大部分的篩選屬性 (例如 [Authorize]) 可以套用至控制器或動作層級 (視所需的細微性層級而定)。
錯誤處理和回應快取通常是跨領域關注:
許多跨領域關注都可以使用篩選或自訂中介軟體進行處理。