在 ASP.NET Core MVC 中處理控制器要求
作者:Steve Smith 和 Scott Addie
控制器、動作和動作結果是開發人員使用 ASP.NET Core MVC 建置應用程式的基礎部分。
什麼是控制器?
控制器是用來定義和分組一組動作。 動作 (或「動作方法」) 是控制器上處理要求的方法。 控制器會以邏輯方式將類似動作群組在一起。 這項動作彙總允許統一套用一組通用規則 (例如路由、快取和授權)。 要求會透過路由對應至動作。 控制器會根據每個要求進行啟動和處置。
依照慣例,控制器類別:
- 位於專案的根層級 Controllers 資料夾中。
- 繼承自
Microsoft.AspNetCore.Mvc.Controller
。
控制器是至少下列其中一個條件為 true 的可具現化類別 (通常為公用):
- 類別名稱的尾碼為
Controller
。 - 類別繼承自名稱尾碼為
Controller
的類別。 [Controller]
屬性會套用至該類別。
控制器類別不得具有相關聯的 [NonController]
屬性。
控制器應該遵循明確相依性準則。 有幾種方法可以實作此準則。 如果多個控制器動作需要相同的服務,請考慮使用建構函式插入來要求這些相依性。 如果只有單一動作方法需要服務,請考慮使用動作插入來要求相依性。
在模型檢視控制器模式內,控制器負責初始處理要求和模型具現化。 一般而言,應該在模型內執行商業決策。
控制器會使用模型處理結果 (如果有的話),並傳回適當檢視和其相關聯的檢視資料或 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
,並傳遞匿名物件。「重新導向」結果類型不同於主要用來新增
Location
HTTP 回應標頭的「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]
) 可以套用至控制器或動作層級 (視所需的細微性層級而定)。
錯誤處理和回應快取通常是跨領域關注:
許多跨領域關注都可以使用篩選或自訂中介軟體進行處理。