Чи може хтось мені пояснити 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
Тоді я не вам, щоб відповісти на моє запитання.
бойовий час

12
Якщо я можу знайти Google і відповісти, чому я намагаюся витрачати час на редагування запитань і запитання тут?
бойовий час

3
дякую, що
Vidar

Відповіді:


157

The CreatedAtRouteМетод призначений для повернення URI для новоствореного ресурсу при виклику методу POST для зберігання якої - то новий об'єкт. Отже, якщо ви розміщуєте, наприклад, елемент замовлення, ви можете повернути такий маршрут, як "api / order / 11" (11 очевидно є ідентифікатором замовлення).

До речі, я погоджуюся, що стаття MSDN не корисна для розуміння цього. Маршрут, який ви фактично повернете, буде, природно, залежати від вашої настройки маршруту.


13
Те, що він повертає, насправді є об’єктом CreatedAtRouteNegotiatedContentResult <myObject>! Це те, що ти побачиш, якщо запустиш тест на дію. Однак при запуску в контексті http він поверне серіалізований об'єкт у тілі, але ви повинні побачити заголовок у відповіді із посиланням на ресурс. До речі, якщо ви думаєте, що я відповів на питання, чи можете ви позначити його як відповідь? Ура.
див. Гостріше

3
Дякую, це відповідає на моє запитання.
воєнний стан

2
Маршрут, який ви надали, у відповіді відображається як заголовок Location. Це досить типова поведінка REST
Джефф Мартін

4
@seesharper Якщо MyObject не повертається, АЛЕ ... чому я повинен передавати його в CreatAtRoute? Що з цим робить метод?
Елізабет

6
Чи є спосіб використовувати поточний маршрут? Наприклад, якщо я створюю об’єкт у контролері файлів за допомогою [Route("[controller]")]контролера, що я повертаю (щоб, наприклад, суміжну дію GET можна було викликати з URL-адресою)?
Шиммі Вайцхандлер

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

У ядрі .net WebAPI ви використовуєте цей метод для повернення коду 201, що означає, що об’єкт був створений.

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

Як ви бачите вище, CreatedAtRoute може отримувати 3 параметри:

routeName - це ім'я, яке потрібно ввести методу, який буде URI, який отримає цей ресурс після створення.

routeValues Це об’єкт, що містить значення, які будуть передані методу GET у названому маршруті. Він буде використовуватися для повернення створеного об'єкта

content Це об'єкт, який було створено.

Вищенаведений приклад показує реалізацію двох методів простого контролера з простим методом 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. Зауважте, що перший параметр в CreatAtRoute (routeName) повинен бути однаковим при визначенні Імені методом Get.

  2. Об'єкт другого параметра повинен мати необхідні поля, які ви використовуєте для отримання ресурсу методом Get, ви можете сказати, що це підмножина об'єкта, створеного самим собою

  3. Останній параметр - це об'єкт компанії, отриманий у запиті body у повному вигляді.

ОКОНЧНО

Як кінцевий результат, коли до цього API буде створено повідомлення про створення нової компанії, ви повернете такий маршрут, як "api / company / {id}", який поверне вам щойно створений ресурс

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.