Sposoby wyszukiwań widoków w .NET Core MVC

W dzisiejszym wpisie chciałbym poruszyć temat wbudowanego wyszukiwania widoków w frameworku .Net Core.

Materiał tworzony jest w celach edukacyjnych oraz utrwalania sobie wiedzy

Do ćwiczeń potrzebujemy pusty projekt .Net Core MVC. Generujemy go w wybranych folderze za pomocą narzędzia CLI.

dotnet new web

Po chwili utworzy nam się nowy projekt aplikacji webowej. Możemy go uruchomić za pomocą komendy:

dotnet watch run

Komenda uruchamia nam wewnętrzny serwer środowiska .Net Core. A parametr watch , nasłuchuje zmian w plikach, które podlegają kompilacji i automatycznie buduje i uruchamia serwer.

Do ćwiczeń potrzebujemy skonfigurować odpowiednio klasę Startup.cs, która znajduję się w głównym folderze projektu. Dokładnie musimy zmodyfikować dwie metody: ConfigureServices oraz Configure. Metody te odpowiadają za konfigurację naszej aplikacji.

Ciało naszej funkcji wygląda teraz tak:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}

W metodzie ConfigureServices włączyliśmy framework .Net Core przy użyciu metody AddMvc(), która jest dziedziczona z interfejsu IServiceCollection.

Kolejnym krokiem jest skonfigurowanie metody Configure,

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
     app.UseDeveloperExceptionPage();
     app.UseStatusCodePages();
     app.UseStaticFiles();
     app.UseMvc(options =>
     {
          options.MapRoute(
              name: "default",
              template: "{controller=Home}/{action=Index}/{id?}"
         );
     });
}
  • UseDeveloperExceptionPage – odpowiada za wyświetlanie strony podczas wywołania niespodziewanego wyjątku w naszej aplikacji, pozwala ona nam namierzyć w którym miejscu i dlaczego pojawił się nieoczekiwany problem,
  • UseStatusCodePages – odpowiada za wyświetlanie strony z kodami błędów HTTP, np: jeżeli system routingu nie znajdzie odpowiedniej ścieżki, wtedy dostaniemy stronę z zawartością „Status Code: 404; Not Found” oraz statusem HTTP 404,
  • UseStaticFiles – odpowiada za statyczne pliki dołączane do naszej witryny, np: jeżeli chcemy z poziomu projektu dołączyć pliku ze kodem JavaScriptu lub z plikami CSS.
  • UseMvc – metoda udostępnia nam funkcje lambda, w tym ćwiczeniu wykorzystam tą metodę do wystawienia routingu,

Teraz trochę dłużej o metodzie MapRoute:

W tym przeciążeniu metody MapRoute dodałem dwa parametry. Name odpowiada za nazwę naszego routingu, a parametr template jest odpowiedzialny za wzór naszego routingu. Według tego wzoru zostają dopasowane adresy url do naszych kontrolerów.

Jak możemy zauważyć, wzór naszego routingu wygląda jakoś nietypowo. W nawiasach klamrowych mamy właściwości controller oraz action. Są to słowa kluczowe, które odpowiadają za generowanie linków oraz przypisanie wartości domyślnych. Dla przykładu, w folderze projektu utworzę folder Controllers i umieszczę w nich plik HomeController, a o to ciało pliku:

using Microsoft.AspNetCore.Mvc;

namespace ViewsProject.Controllers
{
    public class HomeController : Controller
    {
        public ViewResult Index()
        {
            ViewBag.Controller = nameof(HomeController);
            ViewBag.Action = nameof(Index);
            return View();
        }
    }
}

Konwencja nazewnictwa frameworka .Net Core MVC wymaga, żeby wszystkie kontrolery były umieszczone w folderze Controllers w katalogu głównym projektu, wtedy framework znajdzie sobie bez problemu ścieżkę do pliku kontrolera, dzięki zachowaniu konwencji. Konwencja także wymaga, żeby nazwy klas i plik kontrolera zawierała po słowie kluczowym słowo Controller, np: jak w naszym przykładzie HomeController albo ViewController. Jak można zauważyć, HomeController dziedziczy po bazowym kontrolerze w przestrzeni nazw Microsoft.AspNetCore.Mvc, który udostępnia szereg bardzo przydatnych metod i właściwości. Dzięki niemu nie musimy ręcznie implementować potrzebnych podstawowych metod.

Następnym krokiem będzie utworzenie ścieżki folderów w naszym projekcie Views/Home oraz utworzenie w nim pliku Index.cshtml.

@{ Layout = null;}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Hello</title>
</head>
<body>
Wnętrze Kontrollera @ViewBag.Controller i akcji @ViewBag.Action
</body>
</html>

Rozszerzenie pliku .cshtml jest to rozszerzenie pliku dla silnika generowania HTML Razor, który jest wbudowany do frameworka .Net Core.

Teraz spróbuj uruchomić aplikację i wpisać adres url, który wyświetli Ci się w konsoli.

W twojej przeglądarce powinien się pojawić taki wynik:

Wnętrze Kontrollera HomeController i akcji Index

Metoda View(), która generuje widoki występuje w czterech przeciążeniach:

  • View()
  • View(Object)
  • View(String)
  • View(String, Object)

Pierwsze przeciążenie metody View() wyszukuje widok po schemacie Views/NazwaKontrolera/NazwaAkcji.cshtml lub w ścieżce Views/Shared/NazwaAkcji.cshtml . W przypadku kontrolera Home i akcji Index, będzie to ścieżka Views/Home/Index.cshtml. Dlatego jest ważna konwencja nazewnictwa oraz konwencja utrzymywania określonych ścieżek do plików aplikacji.

Drugie przeciążenie metody View(Object) wyszukuje identycznie ścieżkę do widoku jak w przykładzie wyżej, tylko dodatkowo dołącza model, który ma być wyświetlony w widoku.

Przeciążenie View(String) jest bardziej złożone, ponieważ potrafi znaleźć plik widoku, który dotyczy innego kontrolera. Wtedy wywołanie tej metody będzie wyglądać tak:
View(Views/Test/List.cshtml)
Musimy pamiętać, żeby podać rozszerzenie pliku, inaczej nasz widok nie zostanie wczytany oraz zostanie rzucony wyjątek.
Kolejnym przykładem jest użycie tego samego widoku w innej akcji kontrolera:

 HomeController
...
public ViewResult List()
 {
      ViewBag.Controller = nameof(HomeController);
      ViewBag.Action = nameof(List);
      return View("Index");
 }

Metoda View zacznie nam przeszukiwać ścieżkę Views/Home. Jeżeli znajdzie widok w folderze Views/Home to nam go wyświetli, jeżeli nie znajdzie pliku to zacznie szukać folderze Views/Shared. Jeżeli taki widok będzie się znajdował to go wyświetli. W sytuacji gdy chcemy skorzystać widoków z folderu Views/Shared, nie musimy podawać pełnej ścieżki ani rozszerzenia pliku. Wystarczy sama nazwa widoku. W lokalizacji Views/Shared powinny się znajdować widoki, które będą współdzielone między innymi kontrolerami.
Oto przykład takiej metody:

 HomeController
...
public ViewResult Shared()
 {
      ViewBag.Controller = nameof(HomeController);
      ViewBag.Action = nameof(List);
      return View("SharedView");
 }

Czwarte przeciążenie metody, to połączenie przeciążenia metody View(string) oraz View(object). Metoda w tym przeciążeniu potrafi nam dołączyć model do wybranego widoku.

Myślę, że pora zakończyć ten wpis, bo już się zrobił bardzo długi a to tylko widoki 🙂 Następny wpis będzie poświęcony obszarom w frameworku .Net Core MVC.

Wszelkie pliki związane z tutorialem można znaleźć pod adresem:
https://github.com/pnkp/Tutorials
oraz dotyczące tego wpisu pod adresem:
https://github.com/pnkp/Tutorials/tree/master/ViewsTutorials/SearchingViews