Widoki częściowe w ASP.NET Core

Przez Steve Smith, Maher JENDOUBI, Rick Anderson i Scott Sauber

Widok częściowy to Razor plik znaczników (.cshtml) bez @page dyrektywy, która renderuje dane wyjściowe HTML w renderowanych danych wyjściowych innego pliku znaczników.

Termin widok częściowy jest używany podczas tworzenia aplikacji MVC, gdzie pliki znaczników są nazywane widokami lub aplikacją Razor Pages, gdzie pliki znaczników są nazywane stronami. Ten temat ogólnie odnosi się do widoków MVC i Razor stron stron jako plików znaczników.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Kiedy używać widoków częściowych

Widoki częściowe to skuteczny sposób:

  • Podziel duże pliki znaczników na mniejsze składniki.

    W dużym, złożonym pliku znaczników składającym się z kilku elementów logicznych istnieje zaleta pracy z każdym elementem izolowanym w widoku częściowym. Kod w pliku znaczników można zarządzać, ponieważ znacznik zawiera tylko ogólną strukturę strony i odwołania do widoków częściowych.

  • Zmniejsz duplikację wspólnej zawartości znaczników w plikach znaczników.

    Gdy te same elementy znaczników są używane w plikach znaczników, widok częściowy usuwa duplikowanie zawartości znaczników do jednego pliku widoku częściowego. Po zmianie znaczników w widoku częściowym aktualizuje renderowane dane wyjściowe plików znaczników, które korzystają z widoku częściowego.

Widoki częściowe nie powinny być używane do obsługi typowych elementów układu. Typowe elementy układu należy określić w plikach _Layout.cshtml .

Nie używaj widoku częściowego, w którym wymagana jest złożona logika renderowania lub wykonywanie kodu w celu renderowania znaczników. Zamiast widoku częściowego użyj składnika widoku.

Deklarowanie widoków częściowych

Widok częściowy to .cshtml plik znaczników bez dyrektywy przechowywanej @page w folderze Views (MVC) lub pages (Razor Pages).

W ASP.NET Core MVC kontroler ViewResult może zwrócić widok lub widok częściowy. W Razor obszarze PageModel Pages obiekt może zwrócić widok częściowy reprezentowany PartialViewResult jako obiekt. Odwoływanie się i renderowanie widoków częściowych zostało opisane w sekcji Odwołanie do widoku częściowego .

W przeciwieństwie do widoku MVC lub renderowania strony, widok częściowy nie uruchamia polecenia _ViewStart.cshtml. Aby uzyskać więcej informacji na temat _ViewStart.cshtmlprogramu , zobacz Układ w ASP.NET Core.

Częściowe nazwy plików widoku często zaczynają się od podkreślenia (_). Ta konwencja nazewnictwa nie jest wymagana, ale pomaga wizualnie odróżnić widoki częściowe od widoków i stron.

Widok częściowy jest plikiem znaczników przechowywanym .cshtml w folderze Views .

Kontroler ViewResult może zwrócić widok lub widok częściowy. Odwoływanie się i renderowanie widoków częściowych zostało opisane w sekcji Odwołanie do widoku częściowego .

W przeciwieństwie do renderowania widoku MVC, widok częściowy nie uruchamia polecenia _ViewStart.cshtml. Aby uzyskać więcej informacji na temat _ViewStart.cshtmlprogramu , zobacz Układ w ASP.NET Core.

Częściowe nazwy plików widoku często zaczynają się od podkreślenia (_). Ta konwencja nazewnictwa nie jest wymagana, ale pomaga wizualnie odróżnić częściowe widoki od widoków.

Odwołanie do widoku częściowego

Używanie widoku częściowego Razor w modelu PageModel stron

W ASP.NET Core 2.0 lub 2.1 następująca metoda obsługi renderuje widok częściowy _AuthorPartialRP.cshtml do odpowiedzi:

public IActionResult OnGetPartial() =>
    new PartialViewResult
    {
        ViewName = "_AuthorPartialRP",
        ViewData = ViewData,
    };

W ASP.NET Core 2.2 lub nowszej metoda obsługi może alternatywnie wywołać Partial metodę w celu utworzenia PartialViewResult obiektu:

public IActionResult OnGetPartial() =>
    Partial("_AuthorPartialRP");

Używanie widoku częściowego w pliku znaczników

W pliku znaczników istnieje kilka sposobów odwołowania się do widoku częściowego. Zalecamy, aby aplikacje używały jednego z następujących metod asynchronicznego renderowania:

W pliku znaczników istnieją dwa sposoby odwołowania się do widoku częściowego:

Zalecamy, aby aplikacje korzystały z asynchronicznego pomocnika HTML.

Pomocnik tagu częściowego

Pomocnik tagów częściowych wymaga ASP.NET Core 2.1 lub nowszej wersji.

Pomocnik tagów częściowych renderuje zawartość asynchronicznie i używa składni przypominającej kod HTML:

<partial name="_PartialName" />

Gdy rozszerzenie pliku jest obecne, pomocnik tagów odwołuje się do widoku częściowego, który musi znajdować się w tym samym folderze co plik znaczników wywołujący widok częściowy:

<partial name="_PartialName.cshtml" />

Poniższy przykład odwołuje się do widoku częściowego z katalogu głównego aplikacji. Ścieżki rozpoczynające się od ukośnika tyldy () lub ukośnika (~//) odwołują się do katalogu głównego aplikacji:

Razor Stron

<partial name="~/Pages/Folder/_PartialName.cshtml" />
<partial name="/Pages/Folder/_PartialName.cshtml" />

MVC

<partial name="~/Views/Folder/_PartialName.cshtml" />
<partial name="/Views/Folder/_PartialName.cshtml" />

Poniższy przykład odwołuje się do widoku częściowego ze ścieżką względną:

<partial name="../Account/_PartialName.cshtml" />

Aby uzyskać więcej informacji, zobacz Pomocnik tagów częściowych w ASP.NET Core.

Asynchroniczny pomocnik HTML

W przypadku korzystania z pomocnika HTML najlepszym rozwiązaniem jest użycie polecenia PartialAsync. PartialAsyncIHtmlContent zwraca typ opakowany w obiekcie Task<TResult>. Metoda jest przywoływana przez prefiks oczekiwanego wywołania z znakiem @ :

@await Html.PartialAsync("_PartialName")

Gdy rozszerzenie pliku jest obecne, pomocnik HTML odwołuje się do widoku częściowego, który musi znajdować się w tym samym folderze co plik znaczników wywołujący widok częściowy:

@await Html.PartialAsync("_PartialName.cshtml")

Poniższy przykład odwołuje się do widoku częściowego z katalogu głównego aplikacji. Ścieżki rozpoczynające się od ukośnika tyldy () lub ukośnika (~//) odwołują się do katalogu głównego aplikacji:

Razor Stron

@await Html.PartialAsync("~/Pages/Folder/_PartialName.cshtml")
@await Html.PartialAsync("/Pages/Folder/_PartialName.cshtml")

MVC

@await Html.PartialAsync("~/Views/Folder/_PartialName.cshtml")
@await Html.PartialAsync("/Views/Folder/_PartialName.cshtml")

Poniższy przykład odwołuje się do widoku częściowego ze ścieżką względną:

@await Html.PartialAsync("../Account/_LoginPartial.cshtml")

Alternatywnie można renderować widok częściowy za pomocą polecenia RenderPartialAsync. Ta metoda nie zwraca elementu IHtmlContent. Przesyła strumieniowo renderowane dane wyjściowe bezpośrednio do odpowiedzi. Ponieważ metoda nie zwraca wyniku, musi być wywoływana w Razor bloku kodu:

@{
    await Html.RenderPartialAsync("_AuthorPartial");
}

Ponieważ RenderPartialAsync strumienie są renderowane, zapewnia lepszą wydajność w niektórych scenariuszach. W sytuacjach krytycznych dla wydajności przeprowadź test porównawczy strony przy użyciu obu metod i użyj podejścia, które generuje szybszą odpowiedź.

Synchroniczny pomocnik HTML

Partial i RenderPartial są odpowiednio synchronicznymi odpowiednikami PartialAsync i RenderPartialAsync. Odpowiedniki synchroniczne nie są zalecane, ponieważ istnieją scenariusze, w których zakleszczają. Metody synchroniczne są przeznaczone do usunięcia w przyszłej wersji.

Ważne

Jeśli musisz wykonać kod, użyj składnika widoku zamiast widoku częściowego.

Wywoływanie Partial lub RenderPartial powoduje wyświetlenie ostrzeżenia analizatora programu Visual Studio. Na przykład obecność Partial zwraca następujący komunikat ostrzegawczy:

Użycie metody IHtmlHelper.Partial może spowodować zakleszczenia aplikacji. Rozważ użycie <częściowego> pomocnika tagów lub IHtmlHelper.PartialAsync.

Zastąp @await Html.PartialAsync wywołania do @Html.Partial elementu lub pomocnika tagów częściowych. Aby uzyskać więcej informacji na temat migracji pomocnika tagów częściowych, zobacz Migrowanie z pomocnika HTML.

Częściowe odnajdywanie widoku

Gdy widok częściowy jest przywoływane według nazwy bez rozszerzenia pliku, następujące lokalizacje są wyszukiwane w określonej kolejności:

Razor Stron

  1. Obecnie wykonywanie folderu strony
  2. Wykres katalogu nad folderem strony
  3. /Shared
  4. /Pages/Shared
  5. /Views/Shared

MVC

  1. /Areas/<Area-Name>/Views/<Controller-Name>
  2. /Areas/<Area-Name>/Views/Shared
  3. /Views/Shared
  4. /Pages/Shared
  1. /Areas/<Area-Name>/Views/<Controller-Name>
  2. /Areas/<Area-Name>/Views/Shared
  3. /Views/Shared

Następujące konwencje dotyczą odnajdywania częściowego widoku:

  • Różne widoki częściowe o tej samej nazwie pliku są dozwolone, gdy widoki częściowe znajdują się w różnych folderach.
  • W przypadku odwoływania się do widoku częściowego według nazwy bez rozszerzenia pliku i widoku częściowego znajduje się zarówno w folderze wywołującego, jak i w folderze Udostępniony , widok częściowy w folderze wywołującego dostarcza widok częściowy. Jeśli widok częściowy nie znajduje się w folderze obiektu wywołującego, widok częściowy jest udostępniany z folderu Udostępnione . Widoki częściowe w folderze Udostępnione są nazywane widokami częściowym lub domyślnymi widokami częściowym.
  • Widoki częściowe można połączyć w łańcuch — widok częściowy może wywołać inny widok częściowy, jeśli odwołanie cykliczne nie jest tworzone przez wywołania. Ścieżki względne są zawsze względne względem bieżącego pliku, a nie do katalogu głównego lub nadrzędnego pliku.

Uwaga

Element Razorsection zdefiniowany w widoku częściowym jest niewidoczny dla nadrzędnych plików znaczników. Element section jest widoczny tylko dla widoku częściowego, w którym jest zdefiniowany.

Uzyskiwanie dostępu do danych z widoków częściowych

Gdy zostanie utworzone wystąpienie widoku częściowego, otrzyma kopię słownika nadrzędnego ViewData . Aktualizacje wykonane do danych w widoku częściowym nie są utrwalane w widoku nadrzędnym. ViewData zmiany w widoku częściowym zostaną utracone po powrocie widoku częściowego.

W poniższym przykładzie pokazano, jak przekazać wystąpienie ViewDataDictionary do widoku częściowego:

@await Html.PartialAsync("_PartialName", customViewData)

Model można przekazać do widoku częściowego. Model może być obiektem niestandardowym. Model można przekazać PartialAsync (renderuje blok zawartości do obiektu wywołującego) lub RenderPartialAsync (przesyła strumieniowo zawartość do danych wyjściowych):

@await Html.PartialAsync("_PartialName", model)

Razor Stron

Poniższy znacznik w przykładowej aplikacji pochodzi ze Pages/ArticlesRP/ReadRP.cshtml strony. Strona zawiera dwa częściowe widoki. Drugi widok częściowy przechodzi w modelu i ViewData do widoku częściowego. Przeciążenie ViewDataDictionary konstruktora służy do przekazywania nowego ViewData słownika przy zachowaniu istniejącego ViewData słownika.

@model ReadRPModel

<h2>@Model.Article.Title</h2>
@* Pass the author's name to Pages\Shared\_AuthorPartialRP.cshtml *@
@await Html.PartialAsync("../Shared/_AuthorPartialRP", Model.Article.AuthorName)
@Model.Article.PublicationDate

@* Loop over the Sections and pass in a section and additional ViewData to 
   the strongly typed Pages\ArticlesRP\_ArticleSectionRP.cshtml partial view. *@
@{
    var index = 0;

    foreach (var section in Model.Article.Sections)
    {
        await Html.PartialAsync("_ArticleSectionRP", 
                                section,
                                new ViewDataDictionary(ViewData)
                                {
                                    { "index", index }
                                });

        index++;
    }
}

Pages/Shared/_AuthorPartialRP.cshtml jest pierwszym widokiem częściowym, ReadRP.cshtml do których odwołuje się plik znaczników:

@model string
<div>
    <h3>@Model</h3>
    This partial view from /Pages/Shared/_AuthorPartialRP.cshtml.
</div>

Pages/ArticlesRP/_ArticleSectionRP.cshtml jest drugim widokiem częściowym przywoływanym ReadRP.cshtml przez plik znaczników:

@using PartialViewsSample.ViewModels
@model ArticleSection

<h3>@Model.Title Index: @ViewData["index"]</h3>
<div>
    @Model.Content
</div>

MVC

Poniższy znacznik w przykładowej aplikacji pokazuje Views/Articles/Read.cshtml widok. Widok zawiera dwa widoki częściowe. Drugi widok częściowy przechodzi w modelu i ViewData do widoku częściowego. Przeciążenie ViewDataDictionary konstruktora służy do przekazywania nowego ViewData słownika przy zachowaniu istniejącego ViewData słownika.

@model PartialViewsSample.ViewModels.Article

<h2>@Model.Title</h2>
@* Pass the author's name to Views\Shared\_AuthorPartial.cshtml *@
@await Html.PartialAsync("_AuthorPartial", Model.AuthorName)
@Model.PublicationDate

@* Loop over the Sections and pass in a section and additional ViewData to 
   the strongly typed Views\Articles\_ArticleSection.cshtml partial view. *@
@{
    var index = 0;

    foreach (var section in Model.Sections)
    {
        @(await Html.PartialAsync("_ArticleSection", 
                                section,
                                new ViewDataDictionary(ViewData)
                                {
                                    { "index", index }
                                }))

        index++;
    }
}

Views/Shared/_AuthorPartial.cshtml jest pierwszym widokiem częściowym, Read.cshtml do których odwołuje się plik znaczników:

@model string
<div>
    <h3>@Model</h3>
    This partial view from /Views/Shared/_AuthorPartial.cshtml.
</div>

Views/Articles/_ArticleSection.cshtml jest drugim widokiem częściowym przywoływanym Read.cshtml przez plik znaczników:

@using PartialViewsSample.ViewModels
@model ArticleSection

<h3>@Model.Title Index: @ViewData["index"]</h3>
<div>
    @Model.Content
</div>

W czasie wykonywania części są renderowane w renderowanych danych wyjściowych pliku znaczników nadrzędnych, które są renderowane w udostępnionym _Layout.cshtmlpliku . Pierwszy widok częściowy renderuje nazwę i datę publikacji artykułu:

Abraham Lincoln

Ten widok częściowy ze <udostępnionej ścieżki> pliku widoku częściowego. 11/19/1863 12:00:00

Drugi widok częściowy renderuje sekcje artykułu:

Indeks 1 sekcji: 0

Cztery wyniki i siedem lat temu ...

Sekcja Druga indeks: 1

Teraz jesteśmy zaangażowani w wielką wojnę domową, testowanie ...

Sekcja trzy indeksy: 2

Ale, w większym sensie, nie możemy dedykować ...

Dodatkowe zasoby