Tworząc jakiś system prędzej czy później trafimy na taki widok w naszej aplikacji, który się powtarza w wielu miejscach. Czasami jest to dokładnie ten sam widok, z tymi samymi danymi, a czasami ten sam widok, ale z różnymi danymi.

Żeby nie kopiować w wiele miejsc tego samego kodu, można użyć w ASP.NET CORE widoków częściowych, czyli partial views.

Krótki opis

Widok częściowy jest to kod, który można umieszczać w innych widokach. Takich widoków na jednej stronie możemy umieścić bardzo dużo :-) Pisząc widok, mam na myśli zarówno widoki z ASP.NET MVC (views), jak i strony (pages) z Razor Pages.

Do czego może nam to się przydać:

  • Na wielu stronach mamy informacje podane w tabeli. Układ tabeli jest zawsze taki sam, a zmieniają się na przykład dane.
  • Komentarze na stronie – każdy komentarz to będzie wygenerowany widok częściowy.

Cechy

  • Nie zawiera logiki biznesowej.
  • Trzeba do widoku częściowego przekazać jakieś dane.
  • Przyjęta konwencja jest taka, że nazwy widoków częściowych zaczynają się od znaku podkreślenia _ np. _UsersTimeTable.cshtml. Nie jest to wymagane, ale dzięki temu widać od razu, które widoki są częściowe, a które nie.

W ASP.NET Core do dzielenia widoków na mniejsze części można jeszcze użyć ViewComponent. Po polsku to będzie komponent widoku? Trochę dziwnie to brzmi więc nie będę tego spolszczał :-) Główna różnica między ViewComponent, a Partial View jest taka, że ViewComponent może wykonać jakiś kod, nie zawiera tylko kodu Razor. Jest samodzielnym komponentem, który sam pobierze sobie niezbędne dane. Nie jest zależny od innych widoków. To tak w skrócie, może opiszę to jeszcze w innym poście.

Przykład

W mojej aplikacji na kilku stronach pokazuję czas gry użytkowników w różnym okresie: dzień, tydzień, miesiąc. Na każdej stronie pokazuje taką samą tabelkę:

@using ViewModels
@model List<UserTimeViewModel>

<table class="table table-striped table-bordered ">
    <thead>
        <tr>
            <th>Użytkownik</th>
            <th>Czas gry [hh/mm/ss]</th>
        </tr>
    </thead>
    <tbody>

        @foreach (var user in Model)
        {
            <tr>
                <td>@user.UserName</td>
                <td>@user.PlayTimeFriendlyString</td>
            </tr>
        }
    </tbody>
</table>

Widok częściowy w większości wygląda jak standardowy widok. Nie ma w w nim na początku deklaracji @page oraz sekcji z tytułem strony. Na początku widzimy deklarację @using, następnie z jakiego modelu korzysta, a potem już kod widoku.

Wywołanie takiego widoku wygląda tak:

@await Html.PartialAsync("_UsersTimeTable", Model.ViewModel)

Pierwszy parametr to nazwa widoku, drugi to dane potrzebne widokowi.

Ja w projekcie mam tylko jeden widok częściowy dlatego nazwę widoku wpisałem bez rozszerzenia i bez całej ścieżki do pliku. Mój widok znajduje się w tym samym katalogu, gdzie są widoki, które z niego korzystają.

Co zrobić jeśli nasza aplikacja jest bardziej rozbudowana i mamy widoki o takich samych nazwach, ale znajdujące się w innych katalogach? Nic nie stoi na przeszkodzie, aby przekazać pełną ścieżkę do widoku, aby framework wiedział, którego widoku ma użyć.

@await Html.PartialAsync("~/Pages/Users/_UsersTimeTable.cshtml", 
Model.ViewModel)

Microsoft zaleca używania wywołania asynchronicznego. Jest jeszcze kilka sposobów na wywołanie widoku, jeśli jesteś ich ciekawe odsyłam do oficjalnej dokumentacji: Partial views in ASP.NET Core.

Podsumowanie

I tyle :-)

Można w łatwy sposób, bez powielania tego samego kodu na wielu stronach, pokazywać treść w taki sam sposób.

Źródła: https://docs.microsoft.com/pl-pl/aspnet/core/mvc/views/partial?view=aspnetcore-3.1