首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在asp net核心api中使用创建的(或CreatedAtAction / CreatedAtRoute)

如何在asp net核心api中使用创建的(或CreatedAtAction / CreatedAtRoute)
EN

Stack Overflow用户
提问于 2017-12-22 10:30:04
回答 3查看 42.8K关注 0票数 52

我想将新创建的对象的位置告知api的使用者。我知道有Created()CreatedAtRoute()CreatedAtAction(),但我不知道如何使用它。

以下是我尝试过的:

我有一个Get资源,我想指出这个资源。它以一个ID作为输入:

代码语言:javascript
运行
复制
    [HttpGet("/${id}", Name = "GetProduct")]
    [ProducesResponseType(typeof(Produkt), 200)]
    public IActionResult Get([FromRoute] int id)
    {
       // some code...
        return Ok(...);
    }

当通过我的POST路由创建产品时,我想通过位置头指向此资源:

尝试1

代码语言:javascript
运行
复制
    [HttpPost]
    [ProducesResponseType(typeof(Produkt), 200)]
    public IActionResult CreateNewProduct([FromBody] ProduktDtoForCreate productFromBody)
    {
        //...
        return CreatedAtRoute("GetProduct", new { id = productToCreate.Id }, productToCreate);
    }

这将返回:http://localhost:5000/$15003位置标头

尝试2

代码语言:javascript
运行
复制
    [HttpPost]
    [ProducesResponseType(typeof(Produkt), 200)]
    public IActionResult CreateNewProduct([FromBody] ProduktDtoForCreate productFromBody)
    {
        //...
        return Created(new Uri($"{Request.Path}/{productToCreate.Id}", UriKind.Relative), productToCreate);
    }

这个方法可以工作并返回/api/v1.0/produkte/16004,但是似乎不需要使用当前的请求来指向新的位置。另外,我也不确定这是否是好的做法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-12-22 23:40:18

在Get方法的路由中,同时取头/和$ out (即它应该是"{id}")。有前导/在其中意味着该路由将相对于应用程序的基础;将其取出将使该方法相对于控制器的基本路径形成路由。在路由中,$被视为一个文字字符,因此它出现在尝试1中的Location头中。一旦您做了这些更改,您应该会发现您的CreatedAtRoute调用与您预期的一样工作。

票数 6
EN

Stack Overflow用户

发布于 2020-10-12 09:54:26

在我看来,CreatedAtAction提供了最好的输出。以下控制器代码将满足您的需要:

代码语言:javascript
运行
复制
[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);
    }
}

发出下列请求:

代码语言:javascript
运行
复制
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" }

将产生以下答复:

代码语言:javascript
运行
复制
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"}
票数 38
EN

Stack Overflow用户

发布于 2020-07-18 21:30:34

引用RFC 7231

201 (已创建)状态代码指示请求已被满足,并已导致创建一个或多个新资源。由请求创建的主要资源由响应中的位置标头字段标识,或者,如果没有接收到位置字段,则由有效请求URI标识。

什么标识资源取决于上下文。根据我的解释,如果创建的资源位于<request_uri>/<id>,则标识符可以是<id>

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47939945

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档