Ris*_*cie 13 asp.net asp.net-core
我想告诉消费者我的api关于新创建的对象的位置.我知道有Created() CreatedAtRoute(),CreatedAtAction()但我不确定如何使用它.
这是我尝试过的:
我有一个Get资源,我想指出.它需要一个ID作为输入:
[HttpGet("/${id}", Name = "GetProduct")]
[ProducesResponseType(typeof(Produkt), 200)]
public IActionResult Get([FromRoute] int id)
{
// some code...
return Ok(...);
}
Run Code Online (Sandbox Code Playgroud)
当通过我的POST路由创建产品时,我想通过Location标头指向此资源:
尝试1
[HttpPost]
[ProducesResponseType(typeof(Produkt), 200)]
public IActionResult CreateNewProduct([FromBody] ProduktDtoForCreate productFromBody)
{
//...
return CreatedAtRoute("GetProduct", new { id = productToCreate.Id }, productToCreate);
}
Run Code Online (Sandbox Code Playgroud)
这将返回一个位置标头:http:// localhost:5000 / $ 15003
尝试2
[HttpPost]
[ProducesResponseType(typeof(Produkt), 200)]
public IActionResult CreateNewProduct([FromBody] ProduktDtoForCreate productFromBody)
{
//...
return Created(new Uri($"{Request.Path}/{productToCreate.Id}", UriKind.Relative), productToCreate);
}
Run Code Online (Sandbox Code Playgroud)
这个工作并返回/api/v1.0/produkte/16004但似乎不应该使用当前请求指向新位置.另外我不确定这是不是很好的做法?
phi*_*ngs 14
CreatedAtAction在我看来,给出了最好的输出。以下控制器代码将满足您的需求:
[Route("api/products")]
[ApiController]
public class ProductsController : ControllerBase
{
private readonly IProductRepository productRepository;
public ProductsController(IProductRepository productRepository)
{
this.productRepository = productRepository;
}
[HttpPost]
[Route("")]
[ProducesResponseType(StatusCodes.Status201Created)]
public ActionResult<Product> CreateProduct(ProductCreateDto product)
{
if (product is null)
return BadRequest(new ArgumentNullException());
var entity = productRepository.CreateProduct(product);
return CreatedAtAction(nameof(GetProduct), new { id = entity.ID }, entity);
}
[HttpGet]
[Route("{id}")]
public ActionResult<Product> GetProduct(int id)
{
return productRepository.GetProduct(id);
}
}
Run Code Online (Sandbox Code Playgroud)
发出以下请求:
POST http://localhost:5000/api/products HTTP/1.1
Host: localhost:5000
Connection: keep-alive
Content-Length: 25
Content-Type: application/json
{ "name": "ACME Widget" }
Run Code Online (Sandbox Code Playgroud)
将产生以下响应:
HTTP/1.1 201 Created
Date: Mon, 12 Oct 2020 09:50:00 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Content-Length: 29
Location: http://localhost:5000/api/products/1
{"id":1,"name":"ACME Widget"}
Run Code Online (Sandbox Code Playgroud)
在 Get 方法的路线中,将前导 / 和 $ 取出(即它应该只是“{id}”)。有前导 / 在那里意味着路线将相对于应用程序的基础;取出它会使方法的路由相对于控制器的基本路径。$ 被视为路由中的文字字符,因此它出现在尝试 1 中的 Location 标头中。进行更改后,您应该会发现 CreatedAtRoute 调用按预期工作。
| 归档时间: |
|
| 查看次数: |
10598 次 |
| 最近记录: |