Obsługa żądań za pomocą kontrolerów w ASP.NET Core MVC

Przez Steve Smith i Scott Addie

Kontrolery, akcje i wyniki akcji to podstawowa część sposobu tworzenia aplikacji przez deweloperów przy użyciu ASP.NET Core MVC.

Co to jest kontroler?

Kontroler służy do definiowania i grupowania zestawu akcji. Akcja (lub metoda akcji) to metoda na kontrolerze, który obsługuje żądania. Kontrolery logicznie grupują podobne akcje. Ta agregacja akcji umożliwia zbiorcze stosowanie typowych zestawów reguł, takich jak routing, buforowanie i autoryzacja. Żądania są mapowane na akcje za pośrednictwem routingu. Kontrolery są aktywowane i usuwane dla poszczególnych żądań.

Zgodnie z konwencją klasy kontrolerów:

  • Znajduje się w folderze Kontrolery na poziomie głównym projektu.
  • Dziedzicz z Microsoft.AspNetCore.Mvc.Controller.

Kontroler jest wystąpieniem klasy, zwykle publicznej, w której spełniony jest co najmniej jeden z następujących warunków:

  • Nazwa klasy ma sufiks .Controller
  • Klasa dziedziczy z klasy, której nazwa jest sufiksem Controller.
  • Atrybut [Controller] jest stosowany do klasy.

Klasa kontrolera nie może mieć skojarzonego [NonController] atrybutu.

Kontrolery powinny postępować zgodnie z zasadą jawnych zależności. Istnieje kilka podejść do wdrożenia tej zasady. Jeśli wiele akcji kontrolera wymaga tej samej usługi, rozważ użycie wstrzykiwania konstruktora w celu zażądania tych zależności. Jeśli usługa jest wymagana tylko przez jedną metodę akcji, rozważ użycie iniekcji akcji w celu zażądania zależności.

We wzorcu ontroller Model-V iew-C kontroler jest odpowiedzialny za wstępne przetwarzanie żądania i tworzenie wystąpienia modelu. Ogólnie rzecz biorąc, decyzje biznesowe powinny być wykonywane w modelu.

Kontroler pobiera wynik przetwarzania modelu (jeśli istnieje) i zwraca prawidłowy widok i skojarzone z nim dane widoku lub wynik wywołania interfejsu API. Dowiedz się więcej na stronie Omówienie ASP.NET Core MVC i Rozpoczynanie pracy z ASP.NET Core MVC i Visual Studio.

Kontroler jest abstrakcją na poziomie interfejsu użytkownika. Jego obowiązki polegają na upewnieniu się, że dane żądania są prawidłowe i wybrać, który widok (lub wynik dla interfejsu API) powinien zostać zwrócony. W dobrze uwzględnionych aplikacjach nie obejmuje ona bezpośrednio dostępu do danych ani logiki biznesowej. Zamiast tego kontroler deleguje do usług obsługujących te obowiązki.

Definiowanie akcji

Metody publiczne na kontrolerze, z wyjątkiem tych z atrybutem [NonAction] , to akcje. Parametry dotyczące akcji są powiązane z danymi żądania i są weryfikowane przy użyciu powiązania modelu. Walidacja modelu odbywa się dla wszystkich elementów powiązanych z modelem. Wartość ModelState.IsValid właściwości wskazuje, czy powiązanie modelu i walidacja zakończyły się pomyślnie.

Metody akcji powinny zawierać logikę mapowania żądania na problem biznesowy. Problemy biznesowe powinny być zwykle reprezentowane jako usługi, do których kontroler uzyskuje dostęp za pośrednictwem wstrzykiwania zależności. Akcje następnie mapuje wynik akcji biznesowej na stan aplikacji.

Akcje mogą zwracać dowolne elementy, ale często zwracają wystąpienie IActionResult (lub Task<IActionResult> dla metod asynchronicznych), które generuje odpowiedź. Metoda akcji jest odpowiedzialna za wybór rodzaju odpowiedzi. Wynik akcji odpowiada.

Metody pomocnika kontrolera

Kontrolery zwykle dziedziczą z Controllerelementu , chociaż nie jest to wymagane. Wyprowadzanie z Controller zapewnia dostęp do trzech kategorii metod pomocnika:

1. Metody powodujące pustą treść odpowiedzi

Nie Content-Type jest uwzględniony nagłówek odpowiedzi HTTP, ponieważ treść odpowiedzi nie zawiera zawartości do opisania.

Istnieją dwa typy wyników w tej kategorii: Przekierowanie i kod stanu HTTP.

  • Kod stanu HTTP

    Ten typ zwraca kod stanu HTTP. Kilka metod pomocnika tego typu to BadRequest, NotFoundi Ok. Na przykład return BadRequest(); podczas wykonywania tworzy kod stanu 400. Gdy metody takie jak BadRequest, NotFoundi Ok są przeciążone, nie kwalifikują się już jako osoby reagujące kod stanu HTTP, ponieważ odbywa się negocjowanie zawartości.

  • Przekierowanie

    Ten typ zwraca przekierowanie do akcji lub miejsca docelowego (przy użyciu Redirect, , LocalRedirectRedirectToActionlub RedirectToRoute). Na przykład return RedirectToAction("Complete", new {id = 123}); przekierowuje do Completemetody , przekazując anonimowy obiekt.

    Typ wyniku przekierowania różni się od typu kod stanu HTTP przede wszystkim w przypadku dodawania nagłówka Location odpowiedzi HTTP.

2. Metody powodujące niepustą treść odpowiedzi ze wstępnie zdefiniowanym typem zawartości

Większość metod pomocnika w tej kategorii zawiera właściwość umożliwiającą ContentType ustawienie nagłówka Content-Type odpowiedzi w celu opisania treści odpowiedzi.

Istnieją dwa typy wyników w tej kategorii: Wyświetl i Sformatowana odpowiedź.

  • Widok

    Ten typ zwraca widok, który używa modelu do renderowania kodu HTML. Na przykład return View(customer); przekazuje model do widoku powiązania danych.

  • Sformatowana odpowiedź

    Ten typ zwraca JSwartość ON lub podobny format wymiany danych, aby reprezentować obiekt w określony sposób. Na przykład return Json(customer); serializuje podany obiekt w JSformacie ON.

    Inne typowe metody tego typu to i FilePhysicalFile. Na przykład return PhysicalFile(customerFilePath, "text/xml"); zwraca wartość PhysicalFileResult.

3. Metody powodujące niepustą treść odpowiedzi sformatowaną w typie zawartości wynegocjowanym z klientem

Ta kategoria jest lepiej znana jako negocjacje zawartości. Negocjowanie zawartości ma zastosowanie za każdym razem, gdy akcja zwraca ObjectResult typ lub coś innego niż implementacja IActionResult . Akcja zwracająca nieukondycyjnąIActionResult (na przykład object) zwraca również sformatowaną odpowiedź.

Niektóre metody pomocnicze tego typu obejmują BadRequest, CreatedAtRoutei Ok. Przykłady tych metod to return BadRequest(modelState);odpowiednio , return CreatedAtRoute("routename", values, newobject);i return Ok(value);. Należy pamiętać, że BadRequest i Ok wykonać negocjacje zawartości tylko wtedy, gdy przekazano wartość; bez przekazania wartości zamiast tego służą one jako typy wyników kodu stanu HTTP. Z CreatedAtRoute drugiej strony metoda zawsze wykonuje negocjacje zawartości, ponieważ jej przeciążenia wymagają przekazania wartości.

Obawy dotyczące wycinania krzyżowego

Aplikacje zwykle współdzielą części przepływu pracy. Przykłady obejmują aplikację, która wymaga uwierzytelniania w celu uzyskania dostępu do koszyka zakupów lub aplikacji, która buforuje dane na niektórych stronach. Aby wykonać logikę przed lub po metodzie akcji, użyj filtru. Korzystanie z filtrów dotyczących zagadnień krzyżowych może zmniejszyć duplikację.

Większość atrybutów filtru, takich jak [Authorize], można zastosować na poziomie kontrolera lub akcji w zależności od żądanego poziomu szczegółowości.

Obsługa błędów i buforowanie odpowiedzi są często problemami krzyżowymi:

Wiele zagadnień dotyczących wycinania krzyżowego można obsłużyć za pomocą filtrów lub niestandardowego oprogramowania pośredniczącego.