再写一个查询单笔数据的方法:
[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直接进行这个请求: