Vistas parciales en ASP.NET Core

Por Steve Smith, Maher JENDOUBI, Rick Anderson y Scott Sauber

Una vista parcial es un archivo Razorde marcado (.cshtml) sin una directiva @page que renderiza la salida HTML dentro de la salida renderizada de otro archivo de marcado.

El término vista parcial se utiliza cuando se desarrolla una aplicación Modelo-Vista-Controlador, en la que los archivos de marcado se denominan vistas, o una aplicación Razor Pages, donde los archivos de marcado se llaman páginas. Este tema se refiere genéricamente a las vistas MVC y Razor Páginas como archivos de marcado.

Vea o descargue el código de ejemplo (cómo descargarlo)

¿Cuándo se usan las vistas parciales?

Las vistas parciales son una forma eficaz de:

  • Dividir los archivos de marcado grandes en componentes más pequeños.

    En un gran archivo de marcado complejo formado por varias partes lógicas, se ofrece la ventaja de trabajar con cada pieza aislada en una vista parcial. El código del archivo de marcado es fácil de administrar porque el marcado solo contiene la estructura general de la página y las referencias a las vistas parciales.

  • Reducir la duplicación de contenido de marcado común en todos los archivos de marcado.

    Cuando se usan los mismos elementos de marcado en todos los archivos de marcado, una vista parcial elimina la duplicación del contenido de marcado en un archivo de vista parcial. Cuando se cambia el marcado en la vista parcial, actualiza la salida representada de los archivos de marcado que utilizan la vista parcial.

Las vistas parciales no deben utilizarse para mantener los elementos de diseño comunes. Se deben especificar elementos de diseño comunes en los archivos _Layout.cshtml.

No utilice una vista parcial donde se requiera la ejecución de código o lógica de representación compleja para representar el marcado. En lugar de una vista parcial, use un componente de vista.

Declaración de vistas parciales

Una vista parcial es un archivo de marcado .cshtml sin directiva @page que se mantiene dentro de la carpeta Vistas (MVC) o de la carpeta Páginas (Razor Pages).

En ASP.NET Core MVC, la clase ViewResult de un controlador es capaz de devolver una vista o una vista parcial. En Razor Pages, un elemento PageModel puede devolver una vista parcial representada como un objeto PartialViewResult. La referencia y representación de vistas parciales se describe en la sección Referencia a una vista parcial.

A diferencia de la vista MVC o la representación de páginas, una vista parcial no ejecuta _ViewStart.cshtml. Para más información sobre _ViewStart.cshtml, consulte Diseño en ASP.NET Core.

Los nombres de archivo de las vistas parciales suelen comenzar con un guión bajo (_). Esta convención de nomenclatura no es obligatoria, pero ayuda a diferenciar visualmente las vistas parciales de las vistas y las páginas.

Una vista parcial es un archivo de marcado .cshtml que se mantiene dentro de la carpeta Vistas.

La clase ViewResult de un controlador es capaz de devolver una vista o una vista parcial. La referencia y representación de vistas parciales se describe en la sección Referencia a una vista parcial.

A diferencia de la representación de vistas de MVC, una vista parcial no ejecuta _ViewStart.cshtml. Para más información sobre _ViewStart.cshtml, consulte Diseño en ASP.NET Core.

Los nombres de archivo de las vistas parciales suelen comenzar con un guión bajo (_). Esta convención de nomenclatura no es obligatoria, pero ayuda a diferenciar visualmente las vistas parciales de las vistas.

Referencia a una vista parcial

Uso de una vista parcial en una clase PageModel de Razor Pages

En ASP.NET Core 2.0 o 2.1, el método de controlador siguiente representa la vista parcial AuthorPartialRP.cshtml en la respuesta:

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

En ASP.NET Core 2.2 o posterior, un método de controlador puede llamar de forma alternativa al método Partial para generar un objeto PartialViewResult:

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

Uso de una vista parcial en un archivo de marcado

Dentro de un archivo de marcado, hay varias maneras de hacer referencia a una vista parcial. Se recomienda que las aplicaciones usen uno de los siguientes métodos de representación asincrónica:

Dentro de un archivo de marcado, hay dos formas de hacer referencia a una vista parcial:

Se recomienda que las aplicaciones usen el Asistente de HTML asincrónico.

Asistente de etiquetas parciales

El asistente de etiquetas parciales requiere ASP.NET Core 2.1 o posterior.

El asistente de etiquetas parciales representa contenido de forma asincrónica y usa una sintaxis similar a HTML:

<partial name="_PartialName" />

Cuando hay una extensión de archivo, el asistente de etiquetas hace referencia a una vista parcial que debe estar en la misma carpeta que el archivo de marcado que llama a la vista parcial:

<partial name="_PartialName.cshtml" />

En el ejemplo siguiente se hace referencia a una vista parcial desde la raíz de la aplicación. Las rutas de acceso que comienzan con una tilde de la ñ y una barra diagonal (~/) o una barra diagonal (/) hacen referencia a la raíz de la aplicación:

Razor Pages

<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" />

En el ejemplo siguiente se hace referencia a una vista parcial con una ruta de acceso relativa:

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

Para más información, consulte Asistente de etiqueta parcial en ASP.NET Core.

Asistente de HTML asincrónica

Cuando se usa un asistente de HTML, el procedimiento recomendado es usar PartialAsync. PartialAsync devuelve un tipo IHtmlContent encapsulado en una clase Task<TResult>. Para hacer referencia al método, se agrega a la llamada awaited un carácter @ como prefijo:

@await Html.PartialAsync("_PartialName")

Cuando la extensión del archivo está presente, el asistente de HTML hace referencia a una vista parcial que debe estar en la misma carpeta que el archivo de marcado que llama a la vista parcial:

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

En el ejemplo siguiente se hace referencia a una vista parcial desde la raíz de la aplicación. Las rutas de acceso que comienzan con una tilde de la ñ y una barra diagonal (~/) o una barra diagonal (/) hacen referencia a la raíz de la aplicación:

Razor Pages

@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")

En el ejemplo siguiente se hace referencia a una vista parcial con una ruta de acceso relativa:

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

También puede representar una vista parcial con RenderPartialAsync. Este método no devuelve IHtmlContent. sino que transmite por secuencias la salida representada directamente a la respuesta. Debido a que el método no devuelve un resultado, debe ser llamado dentro de un bloque de código Razor:

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

Puesto que RenderPartialAsync transmite contenido representado, ofrece mayor rendimiento en algunos escenarios. En situaciones críticas de rendimiento, realice pruebas comparativas de la página con ambos métodos y use el que genera una respuesta más rápida.

Asistente de HTML sincrónico

Partial y RenderPartial son los equivalentes sincrónicos de PartialAsync y RenderPartialAsync, respectivamente. Los equivalentes sincrónicos no son aconsejables, ya que hay escenarios donde producen interbloqueos. Se prevé la eliminación de los métodos sincrónicos en una futura versión.

Importante

Si no necesita ejecutar código, use un componente de vista en lugar de una vista parcial.

La llamada a Partial o RenderPartial resulta en una advertencia del analizador de Visual Studio. Por ejemplo, la presencia de Partial genera el siguiente mensaje de advertencia:

Use of IHtmlHelper.Partial may result in application deadlocks. Considere la posibilidad de utilizar el asistente de etiquetas <parciales> o IHtmlHelper.PartialAsync.

Reemplace las llamadas a @Html.Partial por @await Html.PartialAsync o el asistente de etiquetas parciales. Para más información sobre la migración del asistente de etiquetas parciales, vea Migración desde un asistente de HTML.

Detección de vistas parciales

Cuando se hace referencia a una vista parcial por su nombre sin una extensión de archivo, se busca en las siguientes ubicaciones en el orden indicado:

Razor Pages

  1. Carpeta de la página en ejecución actualmente
  2. Gráfico de directorio por encima de la carpeta de la página
  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

Las convenciones siguientes se aplican a la detección de la vista parcial:

  • Se admiten diferentes vistas parciales con el mismo nombre de archivo cuando las vistas parciales están en carpetas diferentes.
  • Al hacer referencia a una vista parcial por su nombre sin una extensión de archivo y la vista parcial está presente tanto en la carpeta del autor de la llamada como en la carpeta compartida, la vista parcial de la carpeta del autor de la llamada proporciona la vista parcial. Si la vista parcial no está presente en la carpeta del autor de la llamada, se proporciona la vista parcial desde la carpeta compartida. Las vistas parciales de la carpeta compartida se denominan vistas parciales compartidas o vistas parciales predeterminadas.
  • Las vistas parciales se pueden encadenar: una vista parcial puede llamar a otra vista parcial si las llamadas no forman una referencia circular. Las rutas de acceso relativas siempre guardan relación con el archivo actual, no con la raíz ni el elemento primario del archivo.

Nota:

Una Razorsection definida en una vista parcial es invisible para los archivos de marcado primario. La section solo es visible para la vista parcial en la que está definida.

Acceso a datos desde vistas parciales

Cuando se crea una instancia de una vista parcial, recibe una copia del diccionario ViewData del elemento primario. Las actualizaciones realizadas en los datos dentro de la vista parcial no se conservan en la vista principal. Los cambios de ViewData en una vista parcial se pierden cuando se devuelve la vista parcial.

El siguiente ejemplo muestra cómo pasar una instancia de ViewDataDictionary a una vista parcial:

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

Puede pasar un modelo a una vista parcial. El modelo puede ser un objeto personalizado. Puede pasar un modelo con PartialAsync (representa un bloque de contenido al autor de la llamada) o RenderPartialAsync (transmite el contenido a la salida):

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

Razor Pages

El siguiente marcado en la aplicación de ejemplo es de la página Pages/ArticlesRP/ReadRP.cshtml. La página contiene dos vistas parciales. La segunda vista parcial se pasa a un modelo y ViewData a la vista parcial. La sobrecarga del constructor de ViewDataDictionary se usa para pasar un nuevo diccionario ViewData a la vez que conserva el diccionario ViewData existente.

@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 es la primera vista parcial a la que hace referencia el archivo de marcas ReadRP.cshtml:

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

Pages/ArticlesRP/_ArticleSectionRP.cshtml es la segunda vista parcial referenciada por el archivo de marcado ReadRP.cshtml:

@using PartialViewsSample.ViewModels
@model ArticleSection

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

MVC

El siguiente marcado en la aplicación de ejemplo muestra la vista Views/Articles/Read.cshtml. La vista contiene dos vistas parciales. La segunda vista parcial se pasa a un modelo y ViewData a la vista parcial. La sobrecarga del constructor de ViewDataDictionary se usa para pasar un nuevo diccionario ViewData a la vez que conserva el diccionario ViewData existente.

@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 es la primera vista parcial a la que hace referencia el archivo de marcas Read.cshtml:

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

Views/Articles/_ArticleSection.cshtml es la segunda vista parcial referenciada por el archivo de marcado Read.cshtml:

@using PartialViewsSample.ViewModels
@model ArticleSection

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

En tiempo de ejecución, las vistas parciales se renderizan en la salida renderizada del archivo de marcado padre, que a su vez se renderiza dentro de la _Layout.cshtml compartida. La primera vista parcial representa la fecha de publicación y el nombre del autor del artículo:

Abraham Lincoln

Esta vista parcial procede de la <ruta de acceso de archivo de la vista parcial compartida>. 19/11/1863 12:00:00 a. m.

La segunda vista parcial representa las secciones del artículo:

Índice de la sección uno: 0

Puntuación de cuatro y hace siete años...

Índice de la sección dos: 1

Ahora nos encontramos en una verdadera guerra civil, probando...

Índice de la sección tres: 2

Pero, en un sentido amplio, no nos podemos dedicar...

Recursos adicionales