Alguém pode explicar CreatedAtRoute () para mim?

136

No modelo da API da Web 2, um método de postagem é sempre assim:

[ResponseType(typeof(MyDTO))]
public IHttpActionResult PostmyObject(MyDTO myObject)
{
    ...
    return CreatedAtRoute("DefaultApi", new { id = myObject.Id }, myObject);
}

Eu não entendo esse CreatedAtRoute()método Alguém pode me explicar o CreatedAtRoute()método?

marcial
fonte
25
@JohnSaunders é claro que encontrei esses resultados do Google. Meu problema é que esses documentos não me ajudam a entender esse método, depois de lê-los, eu ainda não entendo. É por isso que pergunto aqui.
marcial
11
Eu não respondo minha pergunta então.
marcial
12
Se eu posso pesquisar no Google e encontrar respostas, por que me preocupo em dedicar um tempo para editar as perguntas e fazer aqui?
marcial
3
obrigado por fazer esta pergunta :)
Vidar

Respostas:

157

O CreatedAtRoutemétodo pretende retornar um URI ao recurso recém-criado quando você invoca um método POST para armazenar algum novo objeto. Portanto, se você POSTAR um item do pedido, por exemplo, poderá retornar uma rota como 'api / order / 11' (11 é obviamente o ID do pedido).

BTW Concordo que o artigo do MSDN não serve para entender isso. A rota que você realmente retorna dependerá naturalmente da sua configuração de roteamento.

veja mais nítido
fonte
13
O que ele retorna é realmente um objeto CreatedAtRouteNegotiatedContentResult <myObject>! É o que você verá se executar um teste de unidade em sua ação. No entanto, quando executado no contexto de http, ele retornará o objeto serializado no corpo, mas você deverá ver um cabeçalho na resposta com o link para o recurso. Aliás, se você acha que eu respondi à pergunta, poderia marcar como resposta? Felicidades.
ver mais nítida
3
Obrigado, isso responde à minha pergunta.
marcial
2
A rota que você forneceu aparece como um cabeçalho de local na resposta. Esse é um comportamento REST bastante típico
Jeff Martin
4
@seesharper Quando o MyObject não é retornado, MAS ... por que preciso transmiti-lo ao CreatedAtRoute? O que o método está fazendo com isso?
Elisabeth
6
Existe uma maneira de usar a rota atual? Por exemplo, se eu criar um objeto no controlador de arquivos usando [Route("[controller]")]no controlador, o que eu retornarei (para que a ação GET adjacente possa ser chamada com a URL, por exemplo)?
Shimmy Weitzhandler
17

Quando você usa CreatedAtRoute, o primeiro argumento é o nome do método Get ao recurso. O truque que não é tão óbvio é que, mesmo com o nome do método correto especificado, você deve usar o parâmetro Name no atributo HttpGet para que ele funcione.

Portanto, se o retorno no seu Post for este:

return CreatedAtRoute("Get", new { newModel.Id}, newModel);

Em seguida, o atributo do método Get deve ficar assim, mesmo que o método seja chamado Get:

[HttpGet("{id}", Name = "Get")]

As chamadas para o método Post não apenas retornarão o novo objeto (normalmente como JSON), mas também definirão o cabeçalho Location na resposta ao URI que obteria esse recurso.

Scott Blasingame
fonte
"Isso não apenas retornará o novo objeto (normalmente como JSON), mas também definirá o cabeçalho Location na resposta ao URI que obteria esse recurso." Por "This", você quer dizer HttpGet ou HttpPost? Além disso, o que você quer dizer com "ele definirá o cabeçalho Location na resposta ao URI que obteria esse recurso".
Tran Anh Minh
"Isto" estava se referindo ao método HttpPost (edite a resposta). Quanto à sua pergunta sobre o cabeçalho Localização, é um Cabeçalho Http com o qual o cliente pode decidir fazer algo como redirecionar automaticamente para ele. É um cabeçalho de resposta HTTP padrão ( en.wikipedia.org/wiki/… ).
Scott Blasingame
Você pode atualizar sua resposta para incluir também o significado dos segundo e terceiro parâmetros.
variável
0

Na WebAPI principal .net, você usa esse método para retornar um código 201, o que significa que o objeto foi criado.

[Microsoft.AspNetCore.Mvc.NonAction]
public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute (string routeName, object routeValues, object content);

Como você pode ver acima, o CreatedAtRoute pode receber 3 parâmetros:

routeName É o nome que você deve colocar no método que será o URI que obteria esse recurso após a criação.

routeValues É o objeto que contém os valores que serão passados ​​para o método GET na rota nomeada. Será usado para retornar o objeto criado

conteúdo É o objeto que foi criado.

O exemplo acima mostra a implementação de dois métodos de um controlador simples com um método GET simples com o nome vinculado e o método POST que cria um novo objeto.

namespace BastterAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CompanyController : Controller
    {
        private ICompanyRepository _companyRepository;

        public CompanyController(ICompanyRepository companyRepository)
        {
            _companyRepository = companyRepository;
        }

        [HttpGet("{id}", Name="GetCompany")]
        public IActionResult GetById(int id)
        {
            Company company = _companyRepository.Find(id);

            if (company == null)
            {
                return NotFound();
            }

            return new ObjectResult(company);

        }

        [HttpPost]
        public IActionResult Create([FromBody] Company company)
        {

            if (company == null)
            {
                return BadRequest();
            }

            _companyRepository.Add(company);

            return CreatedAtRoute("GetCompany", new Company { CompanyID = company.CompanyID }, company);

        }


    }
}

IMPORTANTE

  1. Observe que o primeiro parâmetro em CreatedAtRoute (routeName) deve ser o mesmo na definição do Name no método Get.

  2. O objeto no segundo parâmetro precisará ter os campos necessários que você usa para recuperar o recurso no método Get, você pode dizer que é um subconjunto do objeto criado por si mesmo

  3. O último parâmetro é o objeto da empresa recebido na solicitação do corpo em seu formato completo.

FINALMENTE

Como resultado final, quando a postagem para criar uma nova empresa for criada para essa API, você retornará uma rota como 'api / company / {id}' que retornará para você o recurso recém-criado

Bruno Bastos
fonte