Wprowadzenie
Praktycznie w każdej aplikacji webowej, wcześniej czy później, będziemy potrzebowali obsłużyć uwierzytelnianie użytkowników. Dlatego fajnie, że tworząc nowy projekt w Visual Studio, możemy dodać do niego obsługę uwierzytelniania oraz widoki, które to realizują.
Na ogół z czasem chcemy je zmodyfikować, aby były spójne z projektem graficznym samej aplikacji. Czasami również chcemy je rozszerzyć o jakieś dodatkowe funkcjonalności. Wcześniej tej proces był trochę łatwiejszy, ponieważ wszystkie widoki i ich pliki były generowane podczas tworzenia projektu. Natomiast teraz ten proces wygląda trochę inaczej i zauważyłem, że sporo osób ma z tym pewien problem.
Tworzenie nowego projektu
Podczas tworzenia nowego projektu w Visual Studio w pewnym momencie wybieramy szablon, z którego będziemy korzystać. W tym samym widoku możemy również określić, czy chcemy mieć skonfigurowane uwierzytelnianie (punkt 1 na zrzucie poniżej) oraz jaki ma być jego rodzaj (punkt 2):
Na potrzeby wpisu wykorzystam konta użytkowników przechowywanych w aplikacji (punkt 3 powyżej).
Struktura utworzonego projektu wygląda jak na zrzucie poniżej. Inne szablony projektów mają mniej więcej podobną strukturę, szczególnie jeśli chodzi o uwierzytelnianie.
Znaleźć tutaj możemy folder Areas z podfolderem Identity (punkt 1), który może sugerować, że tutaj znajdować się będą widoki związane z uwierzytelnianiem, ale w praktyce jest on pusty, co, jak zauważyłem, często jest zaskoczeniem.
Do tego jest folder Data (punkt 3) z wygenerowaną klasą data context z Entity Framework Core. Służy ona do zapisu danych użytkownika – o tym kiedyś w innym wpisie. Na końcu jest folder Pages z widokami aplikacji, a w nim tylko jeden mały partial (punkt 4) powiązany z uwierzytelnianiem.
Domyślne widoki identity
W ASP.NET Core 2.1 została wprowadzona domyślna biblioteka Razor Pages Microsoft.AspNetCore.Identity.UI, która zawiera widoki i ich logikę związane z uwierzytelnianiem. Jest ona dodawana do projektu w formie pakietu nugeta i odpowiada za obsługę tych widoków.
Ma to swoje plusy i minusy. Dzięki temu, że jest to pakiet nugetowy, możemy go aktualizować tak jak inne pakiety – szczególnie gdy pojawią się jakieś problemy na przykład z bezpieczeństwem. Z drugiej strony nie mamy tych widoków domyślnie w projekcie i nie możemy ich zmodyfikować. Na szczęście to jesteśmy w stanie obejść poprzez generowanie lokalnych wersji widoków.
Rozwiązanie to zostało tak zaprojektowane, że możemy nadpisać widoki, które są w bibliotece, poprzez dodanie plików do projektu w określone miejsca. Wtedy zostanie użyty taki lokalny plik, a w nim możemy nanieść zmiany lub przepisać go w całości od zera.
Generowanie widoków identity
Pliki te można dodać na kilka sposobów, jednym z nich jest skorzystanie z Visual Studio. W tym celu klikamy prawym klawiszem myszy na folder Areas (punkt 1 na zrzucie poniżej), następnie wybieramy Add (punkt 2) oraz New Scaffolded Item (punkt 3):
W oknie, które się pojawi, wybieramy z lewej strony Identity (punkt 1 poniżej) i w środkowej części również Identity (punkt 2):
Musimy chwilkę poczekać na zainstalowanie potrzebnych pakietów. Po chwili zobaczymy okno z listą widoków, które możemy wygenerować:
Wybieramy interesujące nas widoki. Z części możemy w ogóle nie korzystać w aplikacji. Powyżej zaznaczyłem widok logowania (punkt 1) i rejestracji (punkt 2). Następnie wybieramy klasę data contextu (punkt 3) i dodajemy wszystko przyciskiem Add (punkt 4).
Po dłuższej lub krótszej chwili wygenerowane zostaną widoki oraz kilka dodatkowych plików:
Jak wspomniałem wcześniej, pliki wykorzystują Razor Pages, więc mamy plik cshtml z wyglądem strony oraz cshtml.cs z logiką w c#. W tym momencie możemy modyfikować oba pliki i nanosić nasze zmiany. Odpowiadamy również za zawartość tych plików. Wszelkie zmiany, które wprowadzą twórcy biblioteki do nowej wersji, nie będą dla nas dostępne w tych wygenerowanych plikach i ewentualnie sami musimy nanieść je do naszego kodu.
Nadpisanie tylko plików cshtml
W tym momencie nadpisujemy oba pliki. Ale co ciekawe, możemy tylko nadpisać plik cshtml z samym wyglądem. Natomiast możemy dalej korzystać z logiki, która jest pod spodem, bezpośrednio z biblioteki. Więc w momencie aktualizacji biblioteki również ta logika zostanie zaktualizowana i pewne błędy zostaną poprawione. Ale niesie to też ze sobą ewentualne problemy, gdy model danych lub inne elementy dość mocno się zmienią. Na szczęście w miarę łatwo to wyłapać podczas testów po aktualizacji biblioteki. Na ogół po prostu kod się nie skompiluje.
W Razor Pages na początku pliku cshtml znajduje się dyrektywa model, określającą klasę logiki dla danej strony. W tym momencie jest to właśnie klasa z pliku cshtml.cs. Na przykład LoginModel:
Możemy zrezygnować z używania lokalnej klasy i skorzystać z klasy z biblioteki. Dzięki temu nie będziemy musieli trzymać tego kodu w naszym repozytorium, a możemy skupić się tylko na zmianie samego wyglądu widoków, o ile oczywiście nie potrzebujemy zmian w tym pliku.
Aby to osiągnąć musimy zrobić kilka rzeczy. Po pierwsze usuwamy pliki cshtml.cs. Po drugie zmieniamy użycie dyrektywy model i do typu dorzucamy namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal. W efekcie powyższy plik z widokiem logowania wygląda tak:
Na końcu może się okazać, że z dwóch lub więcej plikach _ViewImports.cshtml będziemy musieli usunąć using do naszego lokalnego namespace. Przestanie on istnieć, gdy usuniemy wszystkie pliki cshtml.cs, które wcześniej wygenerowaliśmy. Tutaj najlepiej po prostu spróbować skompilować aplikację i usunąć błędy, które się pojawią.
Na przykład coś takiego:
Visual Studio pokazuje więcej błędów, ale one wynikają z tego jak działa plik _ViewImports.cshtml. Powoduje on dorzucenie jego zawartości do plików cshtml z danego folderu i jego podfolderów, więc w tym przypadku wystarczy usunąć problematycznego usinga z tego pliku i wszystkie błędy znikną.
Po tych krokach możemy tylko skupić się na zmianie samych widoków i dostosować je do docelowego wyglądu aplikacji.
Przykład
Do tego wpisu nie przygotowałem dedykowanego przykładu ponieważ możesz sam/sama łatwo przejść przez poszczególne kroki.
Podsumowanie
Możliwość szybkiego utworzenia aplikacji z widokami oraz logiką do uwierzytelniania jest bardzo fajna i czasami się przydaje. Sam utworzyłem kilka aplikacji, z których użytkownicy korzystają do dzisiaj i są zadowoleni, a aplikacja korzysta z domyślnego wyglądu, a co istotne jesteśmy w stanie domyślne widoki nadpisać i zmodyfikować ich wygląd lub logikę.
1 thought on “Modyfikowanie widoków identity w ASP.NET Core”