ASP.NET Core WebAPI控制器返回型別的最佳選項
前言
從.NET Core 2.1版開始,到目前為止,控制器操作可以返回三種類型的WebApi響應。這三種類型都有自己的優點和缺點,但都缺乏滿足REST和高可測性的選項。
ASP.NET Core中可用的響應型別包括最近釋出的2.2版本
- 具體型別的結果
- IActionResult
- 的ActionResult <T>
最後一個reult選項 ActionResult <T>是在.NET Core 2.1中引入的。我將使用一個簡單的例子來比較使用這三個控制器動作響應型別選項的優缺點。
文章內容
返回HTTP狀態
這是您在WebAPI應用程式開發過程中必須要具備的。雖然可以遵循REST,但是任何程式功能都是由業務需求驅動的。如果由於控制器操作而返回特定型別,您可能偶爾發現的一件事肯定會返回自定義HTTP狀態程式碼。
讓我們看看具有特定型別返回的簡單操作,並讓它們注意比較。
具體型別
[HttpGet("{id}")] public IEnumerable<string> GetById(int id) { if (id>0) { return new List<string>() { "Value1","Value2","Value3" }; } return null; }
我們有了上面的簡單單嗎,如果ID引數大於0,並返回字串列表,反則返回null。轉換成HTTP,對於任何返回的資料,我們將有 200 OK 狀態嗎響應,以下是我使用PostMan的測試結果圖,請參考。
如果沒有資料,我們將會有一個204 No Content 響應。 對於大多數客戶來說,這是非常滿意的,但是假設我們需要返回另一個狀態程式碼,例如,小於0的任何值,我們直接希望告訴客戶傳送的資料無效,理想情況下,我們將會返回404 BadRequest狀態程式碼。
現在這是特定型別選項問題,由於我們的方法,我們不能立即返回400 BadRequest狀態程式碼,如果我們決定丟擲一個異常會導致500 ServerError的響應,這是錯誤的,因為無效資料基本上是客戶端錯誤並且屬於4xx響應程式碼列表。
執行此操作的方法是顯示設定響應狀態碼並返回空值,這樣就可以保留未同步的兩個操作間隙,因為你必須要處理狀態並返回資料。
[HttpGet("{id}")]
public IEnumerable<string> GetById(int id)
{
if (id > 0)
{
return new List<string>()
{
"Value1","Value2","Value3"
};
}
else if (id < 0)
Response.StatusCode = 400;
return null;
}
處理HTTP POST和HTTP PATCH / PUT請求時遇到的問題更多,而不是200 OK,除了之前的400 BadRequest之外,您可能還必須使用201 Created of 202 Accepted HTTP狀態程式碼進行響應,這將是模型驗證的情況。使用不同的狀態程式碼並不是那麼直接,並且您有多條線負責正確的響應,這與其他兩種返回型別不同。
IActionResult
讓我們看看我們如何通過使用IActionResult作為控制器動作的返回型別來解決這個問題
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
if (id > 0)
{
return Ok(new List<String>()
{
"Value1",
"Value2",
"Value3",
});
}
else if (id < 0)
{
return BadRequest();
}
return NoContent();
}
現在我們可以自由使用我們認為適合的狀態程式碼,以告知客戶我們或我們沒有任何限制地處理他的請求。使用IAction結果顯然比返回特定型別例項更先進,讓.NET決定什麼是狀態程式碼。
ActionResult<T>
關於狀態程式碼,IActionResult和ActionResult <T>返回型別同樣適用在從方法返回結果時直接設定狀態程式碼方面會產生很大差異
但是,還有其他方面,ActionResult <T>比IActionResult更高階,更適合從控制器操作方法返回響應。
[HttpGet("{id}")]
public ActionResult<IEnumerable<string>> GetById(int id)
{
if (id > 0)
{
return Ok(new List<String>()
{
"Value1",
"Value2",
"Value3",
});
}
else if (id < 0)
{
return BadRequest();
}
return NoContent();
}
您已經瞭解了ASP.NET MVC Core WebAPI專案中控制器操作的不同響應型別的一些優缺點。很明顯IActionResult和ActionResult <T>是比返回特定型別更好的選擇,雖然您可能會發現在控制器操作中返回特定型別更為舒適,但您可能會使單元測試無法正確覆蓋您的程式碼,因此將來可能會開啟潛在的危險。
總結
具體型別
如果在執行動作期間沒有已知的防範條件,則返回特定型別就足夠了。上述操作不接受任何引數,因此不需要引數約束驗證。
IActionResult型別
當一個動作中有多個ActionResult返回型別時,IActionResult返回型別是合適的。這些型別代表各種HTTP狀態程式碼。屬於此類別的一些常見返回型別是BadRequestResult(400),NotFoundResult(404)和OkObjectResult(200)。
ActionResult <T>型別
大多數操作都有特定的返回型別。在操作執行期間可能發生意外情況,在這種情況下不返回特定型別。例如,操作的輸入引數可能無法通過模型驗證。在這種情況下,通常返回適當的
ActionResult
型別而不是特定型別。