再寫一個查詢單筆數據的方法:
[Route("{id}")]
public JsonResult GetProduct(int id)
{
return new JsonResult(ProductService.Current.Products.SingleOrDefault(x => x.Id == id));
}
這裏Route參數裏面的{id}表示該action有一個參數名字是id. 這個action的地址是: "/api/product/{id}"
測試一下:
如果請求一個id不存在的數據:
Status code還是200, 內容是null. 因爲框架找到了匹配url的action, 所以不會返回404, 但是我們如果找不到數據的話, 應該返回404錯誤才比較好.
Status code
http status code 是reponse的一部分, 它提供了這些信息: 請求是否成功, 失敗的原因.
web api 能涉及到的status codes主要是這些:
200: OK
201: Created, 創建了新的資源
204: 無內容 No Content, 例如刪除成功
400: Bad Request, 指的是客戶端的請求錯誤.
401: 未授權 Unauthorized.
403: 禁止操作 Forbidden. 驗證成功, 但是沒法訪問相應的資源
404: Not Found
409: 有衝突 Conflict.
500: Internal Server Error, 服務器發生了錯誤.
返回Status Code
目前我們返回的JsonResult繼承與ActionResult, ActionResult實現了IActionResult接口.
因爲web api不一定返回的都是json類型的數據, 也不一定只返回一堆json(可能還要包含其他內容). 所以JsonResult並不合適作爲Action的返回結果.
例如: 我們想要返回數據和Status Code, 那麼可以這樣做:
[HttpGet]
public JsonResult GetProducts()
{
var temp = new JsonResult(ProductService.Current.Products)
{
StatusCode = 200
};
return temp;
}
但是每個方法都這麼寫太麻煩了.
asp.net core 內置了很多方法都可以返回IActionResult.
Ok, NotFound, BadRequest等等.
所以改一下方法:
namespace CoreBackend.Api.Controllers
{
[Route("api/[controller]")]
public class ProductController : Controller
{
[HttpGet]
public IActionResult GetProducts()
{
return Ok(ProductService.Current.Products);
}
[Route("{id}")]
public IActionResult GetProduct(int id)
{
var product = ProductService.Current.Products.SingleOrDefault(x => x.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
現在, 請求id不存在的數據時, 就返回404了.
如果我們用chrome直接進行這個請求, 它的效果是這樣的:
StatusCode Middleware
asp.net core 有一個 status code middleware StatusCodePages, 使用一下這個middleware看看效果,在Startup.cs中添加StatusCodePages的使用:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler();
}
app.UseRouting();
app.UseStatusCodePages(); // status code middleware
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
現在更友好了一些.
chrome直接進行這個請求: