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

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

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

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


person martial    schedule 30.07.2014    source источник
comment
@JohnSaunders, конечно, нашел те результаты Google. Моя проблема в том, что эти документы не помогают мне понять этот метод, после их прочтения я все еще не понимаю. Вот почему я спрашиваю здесь.   -  person martial    schedule 31.07.2014
comment
Если я могу погуглить и найти ответ, зачем мне тратить время на то, чтобы редактировать вопрос и задавать здесь?   -  person martial    schedule 01.08.2014
comment
спасибо, что задали этот вопрос :)   -  person Vidar    schedule 09.04.2019


Ответы (3)


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

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

person see sharper    schedule 04.08.2014
comment
Спасибо. Это очень полезно. Но когда я протестировал Postman, я увидел, что возвращается myObject, а не маршрут? - person martial; 05.08.2014
comment
На самом деле он возвращает объект CreatedAtRouteNegotiatedContentResult ‹myObject›! Вот что вы увидите, если запустите модульный тест своего действия. Однако при запуске в контексте http он вернет сериализованный объект в теле, но вы должны увидеть заголовок в ответе со ссылкой на ресурс. Кстати, если вы думаете, что я ответил на вопрос, не могли бы вы отметить ответ? Ваше здоровье. - person see sharper; 08.08.2014
comment
Спасибо, это ответ на мой вопрос. - person martial; 13.08.2014
comment
Указанный вами маршрут отображается в ответе в виде заголовка Location. Это довольно типичное поведение REST - person Jeff Martin; 14.05.2015
comment
Почему я должен возвращать MyObject в CreatedAtRoute, он уже на клиенте ... Только Id новый, который уже находится в анонимном типе ?! - person Elisabeth; 19.06.2015
comment
@Elisa: MyObject не возвращается CreatedAtRoute - только URI нового ресурса. Это будет включать идентификатор, который клиент еще не знает (по крайней мере, в типичном сценарии, когда база данных генерирует идентификатор), и это основная цель метода. Стандартно для REST возвращать это при POSTing нового ресурса, но это не обязательно или что-то в этом роде. Если он вам не нужен, вы можете просто вернуть 201. - person see sharper; 19.06.2015
comment
@seesharper Если MyObject не возвращается, НО ... почему я должен передавать его в CreatedAtRoute? Что с этим делает метод? - person Elisabeth; 19.06.2015
comment
Хорошо, это своего рода ответ на вопрос для простого случая, но как насчет более сложного? Как мне вызвать CreatedAtRoute, если URI, который я хочу вернуть, - это / api / Customers / {customerId} / Order / {orderId}? - person Greg Veres; 22.05.2016
comment
Вот еще одна ссылка на связанный вопрос о CreatedAtRoute, который говорит об именовании маршрутов, когда вы используете атрибуты (то есть для сложных маршрутов, таких как пример клиента, который я привел). Это решило мою проблему с заполнением обоих параметров. - person Greg Veres; 22.05.2016
comment
Есть ли способ использовать текущий маршрут? Например, если я создаю объект в контроллере файлов, используя [Route("[controller]")] на контроллере, что я возвращаю (чтобы, например, можно было вызвать соседнее действие GET с URL-адресом)? - person Shimmy Weitzhandler; 22.12.2017
comment
@seesharper, отвечая Элизабет, вы говорите, что MyObject не возвращается CreatedAtRoute. Хотя в комментарии, который вы сделали ранее в этом потоке, вы говорите, что он возвращается в сериализованной форме в теле. Не могли бы вы прояснить это? Правильно ли я считаю, что и URI ресурса, и сам ресурс (в теле) передаются обратно клиенту из вызова CreatedAtRoute? Если да, то какой смысл включать и то, и другое? - person Evan Sevy; 01.08.2019
comment
@RuneStar хороший вопрос. Я давно не писал этот ответ и какое-то время не работал с веб-API, но да, CreatedAtRoute возвращает местоположение в виде заголовка и сам объект в теле. Так что, похоже, этот комментарий к Элизабет был неправильным. Что касается цели, я предполагаю, что с запросом POST (в отличие от PUT) сервер может создать объект, который не является просто тем, что отправил клиент, и клиент может быть заинтересован в этом и не хочет чтобы нужно было сделать второй запрос к возвращенному URI местоположения. - person see sharper; 01.08.2019
comment
Правильно ли я понимаю, что CreatedAtRoute возвращает созданный объект и ссылку на метод Get. Я изначально думал, что возвращаемый объект создается вызовом метода Get. - person variable; 06.06.2020
comment
@ShimmyWeitzhandler См. этот ответ, чтобы узнать, как получить имя контроллера. . Я не верю, что идея "[controller]" работает вне Route() :( - person Lucas; 27.03.2021

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

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

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

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

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

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

person Scott Blasingame    schedule 20.12.2019
comment
Это не только вернет новый объект (обычно как JSON), но и установит заголовок Location в ответ на URI, который получит этот ресурс. Вы имеете в виду HttpGet или HttpPost? Кроме того, что вы подразумеваете под этим, он установит заголовок Location в ответ на URI, который получит этот ресурс? - person Tran Anh Minh; 27.04.2020
comment
Речь шла о методе HttpPost (отредактируйте ответ). Что касается вашего вопроса о заголовке Location, это заголовок Http, который клиент может решить сделать что-то, например, автоматически перенаправить на него. Это стандартный заголовок ответа Http (en.wikipedia.org/wiki/). - person Scott Blasingame; 30.04.2020
comment
Не могли бы вы обновить свой ответ, включив в него также значение 2-го и 3-го параметра. - person variable; 06.06.2020

В 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}», который вернет вам вновь созданный ресурс.

person Bruno Bastos    schedule 09.05.2020
comment
Этот ответ недооценен. Я действительно понял смысл здесь. - person Navjot Singh; 12.06.2021