Может ли кто-нибудь объяснить мне CreatedAtRoute ()?


136

В шаблоне для Web API 2 метод публикации всегда выглядит следующим образом:

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

Я не понимаю этого CreatedAtRoute()метода. Может ли кто-нибудь объяснить CreatedAtRoute()мне метод?


25
@JohnSaunders, конечно, нашел те результаты Google. Моя проблема в том, что эти документы не помогают мне понять этот метод, после их прочтения я все еще не понимаю. Вот почему я спрашиваю здесь.
боевой

11
Тогда я не стану вам отвечать на мой вопрос.
Martial

12
Если я могу погуглить и найти ответ, зачем мне тратить время на редактирование вопроса и задание здесь?
Martial

3
спасибо, что задали этот вопрос :)
Vidar

Ответы:


157

CreatedAtRouteМетод предназначен для возвращения URI для вновь созданного ресурса при вызове метода POST для хранения какой - то новый объект. Поэтому, если вы, например, ПУБЛИВАЕТЕ элемент заказа, вы можете вернуть такой маршрут, как «api / order / 11» (11, очевидно, является идентификатором заказа).

Кстати, я согласен, что статья MSDN бесполезна для понимания этого. Маршрут, по которому вы действительно вернетесь, будет, естественно, зависеть от вашей настройки маршрута.


13
На самом деле он возвращает объект CreatedAtRouteNegotiatedContentResult <myObject>! Вот что вы увидите, если запустите модульный тест своего действия. Однако при запуске в контексте http он вернет сериализованный объект в теле, но вы должны увидеть заголовок в ответе со ссылкой на ресурс. Кстати, если вы думаете, что я ответил на вопрос, не могли бы вы отметить ответ? Приветствия.
см. Резче

3
Спасибо, это ответ на мой вопрос.
Martial

2
Указанный вами маршрут отображается в ответе в виде заголовка Location. Это довольно типичное REST-поведение
Джефф Мартин

4
@seesharper Когда MyObject не возвращается, НО ... почему я должен передавать его в CreatedAtRoute? Что с этим делает метод?
Элизабет

6
Есть ли способ использовать текущий маршрут? Например, если я создаю объект в контроллере файлов с помощью [Route("[controller]")]контроллера, что я возвращаю (например, чтобы можно было вызвать смежное действие GET с URL-адресом)?
Shimmy Weitzhandler

17

Когда вы используете CreatedAtRoute, первым аргументом является имя метода Get to the resource. Уловка, которая не так очевидна, заключается в том, что даже при указании правильного имени метода вы должны использовать параметр Name в атрибуте HttpGet, чтобы он работал.

Итак, если ответ в вашем сообщении такой:

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

Тогда ваш атрибут метода Get должен выглядеть так, даже если ваш метод назван Get:

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

Вызов вашего метода Post не только вернет новый объект (обычно как JSON), но и установит заголовок Location в ответе на URI, который получит этот ресурс.


«Это не только вернет новый объект (обычно как JSON), но и установит заголовок Location в ответе на URI, который получит этот ресурс». Под «этим» вы имеете в виду HttpGet или HttpPost? Кроме того, что вы имеете в виду под «он установит заголовок Location в ответ на URI, который получит этот ресурс»?
Тран Ань Минь,

«Это» относится к методу HttpPost (отредактируйте ответ). Что касается вашего вопроса относительно заголовка Location, это заголовок Http, который клиент может решить сделать что-то, например, автоматически перенаправить на него. Это стандартный заголовок ответа Http ( en.wikipedia.org/wiki/… ).
Скотт Близингейм,

Не могли бы вы обновить свой ответ, включив в него также значение 2-го и 3-го параметра.
переменная

0

В WebAPI ядра .net этот метод используется для возврата кода 201, что означает, что объект был создан.

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

Как видно выше, CreatedAtRoute может получать 3 параметра:

routeName - это имя, которое вы должны присвоить методу, который будет URI, который получит этот ресурс после создания.

routeValues Это объект, содержащий значения, которые будут переданы методу GET на указанном маршруте. Он будет использоваться для возврата созданного объекта

содержание Это объект, который был создан.

В приведенном выше примере показана реализация двух методов простого контроллера с простым методом GET со связанным именем и методом POST, который создает новый объект.

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);

        }


    }
}

ВАЖНЫЙ

  1. Обратите внимание, что первый параметр в CreatedAtRoute (routeName) должен совпадать с определением Name в методе Get.

  2. Объект во втором параметре должен иметь необходимые поля, которые вы используете для извлечения ресурса в методе Get, вы можете сказать, что это подмножество объекта, созданного самим

  3. Последний параметр - объект компании, полученный в теле запроса в его полной форме.

Финлей

В конечном итоге, когда сообщение о создании новой компании будет добавлено в этот API, вы вернете маршрут типа «api / company / {id}», который вернет вам вновь созданный ресурс.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.