Czy ktoś może mi wyjaśnić CreatedAtRoute ()?

140

Z szablonu dla Web API 2 metoda wpisu jest zawsze następująca:

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

Nie rozumiem tej CreatedAtRoute()metody. Czy ktoś może mi wyjaśnić CreatedAtRoute()metodę?

wojenny
źródło
27
@JohnSaunders oczywiście znalazłem te wyniki Google. Mój problem polega na tym, że te dokumenty nie pomagają mi zrozumieć tej metody, po ich przeczytaniu nadal nie rozumiem. Dlatego pytam tutaj.
wojenny
13
Nie odpowiadam więc na moje pytanie.
wojenny
14
Jeśli mogę znaleźć w Google i znaleźć odpowiedź, dlaczego kłopoczę się poświęcaniem czasu na edycję pytania i zadawanie tutaj pytań?
wojenny
4
dzięki za zadanie tego pytania :)
Vidar

Odpowiedzi:

159

CreatedAtRouteMetoda ma na celu zwrócić URI do nowo utworzonego zasobu podczas wywoływania metody POST do przechowywania nowy obiekt. Więc jeśli na przykład POSTAWASZ przedmiot zamówienia, możesz zwrócić trasę, taką jak „api / order / 11” (11 to oczywiście identyfikator zamówienia).

Przy okazji zgadzam się, że artykuł MSDN nie pomoże w zrozumieniu tego. Trasa, którą faktycznie wracasz, będzie oczywiście zależała od konfiguracji routingu.

zobacz ostrzej
źródło
13
To, co zwraca, jest w rzeczywistości obiektem CreatedAtRouteNegotiatedContentResult <myObject>! To właśnie zobaczysz, jeśli uruchomisz test jednostkowy swojej akcji. Jednak po uruchomieniu w kontekście http zwróci zserializowany obiekt w treści, ale w odpowiedzi powinien pojawić się nagłówek z linkiem do zasobu. Przy okazji, jeśli uważasz, że odpowiedziałem na pytanie, czy możesz oznaczyć jako odpowiedź? Twoje zdrowie.
zobacz ostrzejszy
3
Dziękuję, to odpowiada na moje pytanie.
wojenny
2
Podana trasa zostanie wyświetlona jako nagłówek lokalizacji w odpowiedzi. Jest to dość typowe zachowanie REST
Jeff Martin
4
@seesharper Kiedy MyObject nie jest zwracany, ALE ... dlaczego mam go przekazywać do CreatedAtRoute? Co robi z tym metoda?
Elisabeth
6
Czy jest sposób, aby skorzystać z aktualnej trasy? Na przykład, jeśli utworzę obiekt w kontrolerze plików za pomocą [Route("[controller]")]kontrolera, co zwrócę (aby na przykład sąsiednia akcja GET mogła zostać wywołana za pomocą adresu URL)?
Shimmy Weitzhandler,
18

Gdy używasz CreatedAtRoute, pierwszym argumentem jest nazwa metody Get do zasobu. Sztuczka, która nie jest tak oczywista, polega na tym, że nawet przy określonej poprawnej nazwie metody należy użyć parametru Name w atrybucie HttpGet, aby zadziałała.

Więc jeśli zwrot w Twoim poście jest taki:

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

Wtedy atrybut metody Get powinien wyglądać tak, nawet jeśli twoja metoda nosi nazwę Get:

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

Wywołania Twojej metody Post nie tylko zwrócą nowy obiekt (zwykle jako JSON), ale ustawią nagłówek Location w odpowiedzi na identyfikator URI, który ma uzyskać ten zasób.

Scott Blasingame
źródło
„To nie tylko zwróci nowy obiekt (zwykle w formacie JSON), ale ustawi nagłówek Location w odpowiedzi na identyfikator URI, który uzyska ten zasób”. Przez „to” masz na myśli HttpGet czy HttpPost? Co masz na myśli, mówiąc „ustawi nagłówek Location w odpowiedzi na identyfikator URI, który uzyska ten zasób”?
Tran Anh Minh
„To” odnosiło się do metody HttpPost (edytuj odpowiedź). Jeśli chodzi o twoje pytanie dotyczące nagłówka lokalizacji, to jest to nagłówek HTTP, z którym klient może zdecydować się zrobić coś takiego, jak automatyczne przekierowanie do niego. Jest to standardowy nagłówek odpowiedzi HTTP ( en.wikipedia.org/wiki/ ... ).
Scott Blasingame
Czy możesz zaktualizować swoją odpowiedź, aby uwzględnić również znaczenie drugiego i trzeciego parametru.
zmienna
2

W .net core WebAPI ta metoda służy do zwracania kodu 201, co oznacza, że ​​obiekt został utworzony.

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

Jak widać powyżej, CreatedAtRoute może otrzymać 3 parametry:

routeName to nazwa, którą należy przypisać metodzie, która będzie identyfikatorem URI, który będzie pobierał ten zasób po utworzeniu.

routeValues Jest to obiekt zawierający wartości, które zostaną przekazane do metody GET w nazwanej trasie. Zostanie użyty do zwrócenia utworzonego obiektu

zawartość To obiekt, który został utworzony.

Powyższy przykład pokazuje implementację dwóch metod prostego kontrolera z prostą metodą GET o powiązanej nazwie oraz metodą POST, która tworzy nowy obiekt.

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

        }


    }
}

WAŻNY

  1. Zwróć uwagę, że pierwszy parametr w CreatedAtRoute (routeName) musi być taki sam w definicji Name w metodzie Get.

  2. Obiekt na drugim parametrze będzie musiał mieć niezbędne pola, których używasz do pobierania zasobu w metodzie Get, możesz powiedzieć, że jest to podzbiór obiektu utworzonego samodzielnie

  3. Ostatnim parametrem jest obiekt firmy otrzymany w treści żądania w pełnej postaci.

WRESZCIE

W rezultacie, gdy post o utworzeniu nowej firmy zostanie przesłany do tego interfejsu API, zwrócisz trasę, taką jak „api / company / {id}”, która zwróci Ci nowo utworzony zasób

Bruno Bastos
źródło