Diseño en ASP.NET Core
Por Steve Smith y Dave Brock
Las páginas y las vistas a menudo comparten elementos visuales y elementos mediante programación. En este artículo se explica cómo:
- Usar diseños comunes.
- Compartir directivas.
- Ejecutar código común antes de representar páginas o vistas.
En este documento se describen los diseños de los dos enfoques diferentes para ASP.NET Core MVC: Razor páginas y controladores con vistas. Para este tema, las diferencias son mínimas:
- Razor Las páginas están en la carpeta Pages .
- Los controladores con vistas usan una carpeta Vistas para las vistas.
Qué es un diseño
La mayoría de las aplicaciones web tienen un diseño común que ofrece al usuario una experiencia coherente mientras navegan por sus páginas. El diseño suele incluir elementos comunes en la interfaz de usuario, como el encabezado, los elementos de navegación o de menú y el pie de página de la aplicación.
Las estructuras HTML comunes, como scripts y hojas de estilo, también se usan con frecuencia en muchas páginas dentro de una aplicación. Todos estos elementos compartidos se pueden definir en un archivo de diseño , al que puede hacer referencia cualquier vista utilizada dentro de la aplicación. Los diseños reducen el código duplicado en las vistas.
Por convención, el diseño predeterminado para una aplicación ASP.NET Core se denomina _Layout.cshtml
. Los archivos de diseño para los nuevos proyectos de ASP.NET Core creados con las plantillas son:
Razor Páginas:
Pages/Shared/_Layout.cshtml
Controlador con vistas:
Views/Shared/_Layout.cshtml
Este diseño define una plantilla de nivel superior para las vistas en la aplicación. Las aplicaciones no requieren un diseño. Las aplicaciones pueden definir más de un diseño, con otras vistas que especifiquen otros diseños.
Este código muestra el archivo de diseño para un proyecto creado mediante plantilla con un controlador y vistas:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebApplication1</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-page="/Index" class="navbar-brand">WebApplication1</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-page="/Index">Home</a></li>
<li><a asp-page="/About">About</a></li>
<li><a asp-page="/Contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<partial name="_CookieConsentPartial" />
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2018 - WebApplication1</p>
</footer>
</div>
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("Scripts", required: false)
</body>
</html>
Especificar un diseño
Razor las vistas tienen una Layout
propiedad . Las vistas individuales especifican un diseño al configurar esta propiedad:
@{
Layout = "_Layout";
}
El diseño especificado puede usar una ruta de acceso completa (por ejemplo, /Pages/Shared/_Layout.cshtml
o ) o /Views/Shared/_Layout.cshtml
un nombre parcial (ejemplo: _Layout
). Cuando se proporciona un nombre parcial, el Razor motor de vista busca el archivo de diseño mediante su proceso de detección estándar. Primero se busca la carpeta donde existe el método de controlador (o controlador), seguida de la carpeta Shared. Este proceso de detección es idéntico al que se usa para detectar vistas parciales.
De forma predeterminada, todos los diseños deben llamar a RenderBody
. Cada vez que se realiza la llamada a RenderBody
, se representa el contenido de la vista.
Secciones
Opcionalmente, un diseño puede hacer referencia a una o varias secciones mediante una llamada a RenderSection
. Las secciones permiten organizar dónde se deben colocar determinados elementos de la página. Cada llamada a RenderSection
puede especificar si esa sección es obligatoria u opcional:
<script type="text/javascript" src="~/scripts/global.js"></script>
@RenderSection("Scripts", required: false)
Si no se encuentra una sección obligatoria, se produce una excepción. Las vistas individuales especifican el contenido que se va a representar dentro de una sección mediante la @section
Razor sintaxis . Si una página o una vista define una sección, se debe representar (o se producirá un error).
Una definición de ejemplo @section
en la Razor vista Páginas:
@section Scripts {
<script type="text/javascript" src="~/scripts/main.js"></script>
}
En el código anterior, scripts/main.js
se agrega a la scripts
sección de una página o vista. Es posible que otras páginas o vistas de la misma aplicación no necesiten este script y no definan una sección de script.
El marcado siguiente usa el asistente de etiquetas parciales para representar _ValidationScriptsPartial.cshtml
:
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
El marcado anterior se generó mediante scaffolding Identity.
Las secciones definidas en una vista o una vista solo están disponibles en su página de diseño inmediato. No se puede hacer referencia a ellas desde líneas de código parcialmente ejecutadas, componentes de vista u otros elementos del sistema de vistas.
Omitir secciones
De forma predeterminada, el cuerpo y todas las secciones de una página de contenido deben representarse mediante la página de diseño. El Razor motor de vista aplica esto mediante el seguimiento de si se han representado el cuerpo y cada sección.
Para indicar al motor de vistas que pase por alto el cuerpo o las secciones, llame a los métodos IgnoreBody
y IgnoreSection
.
El cuerpo y todas las secciones de una Razor página deben representarse o omitirse.
Importar directivas compartidas
Las vistas y las páginas pueden usar Razor directivas para importar espacios de nombres y usar la inserción de dependencias. Se pueden especificar varias directivas compartidas por muchas vistas en un archivo _ViewImports.cshtml
común. El archivo _ViewImports
es compatible con estas directivas:
@addTagHelper
@removeTagHelper
@tagHelperPrefix
@using
@model
@inherits
@inject
@namespace
El archivo no admite otras Razor características, como funciones y definiciones de sección.
Archivo _ViewImports.cshtml
de ejemplo:
@using WebApplication1
@using WebApplication1.Models
@using WebApplication1.Models.AccountViewModels
@using WebApplication1.Models.ManageViewModels
@using Microsoft.AspNetCore.Identity
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
El _ViewImports.cshtml
archivo de una aplicación ASP.NET Core MVC se coloca normalmente en la carpeta Pages (o Views). Un _ViewImports.cshtml
archivo se puede colocar dentro de cualquier carpeta, en cuyo caso solo se aplicará a páginas o vistas dentro de esa carpeta y sus subcarpetas. Los archivos _ViewImports
se procesan a partir del nivel de raíz y, después, para cada carpeta que llevó a la ubicación de la propia página o vista. La configuración _ViewImports
especificada en el nivel de raíz se puede reemplazar en el nivel de carpeta.
Por ejemplo, supongamos que:
- El archivo de nivel
_ViewImports.cshtml
raíz incluye@model MyModel1
y@addTagHelper *, MyTagHelper1
. - Un archivo de subcarpeta
_ViewImports.cshtml
incluye@model MyModel2
y@addTagHelper *, MyTagHelper2
.
Las páginas y las vistas de la subcarpeta tendrán acceso a los asistentes de etiquetas y al modelo MyModel2
.
Si se encuentran varios _ViewImports.cshtml
archivos en la jerarquía de archivos, el comportamiento combinado de las directivas es:
@addTagHelper
,@removeTagHelper
: todos se ejecutan en orden@tagHelperPrefix
: el más cercano a la vista invalida los demás@model
: el más cercano a la vista invalida los demás@inherits
: el más cercano a la vista invalida los demás@using
: todos se incluyen y se omiten los duplicados@inject
: para cada propiedad, la más cercana a la vista invalida cualquier otra con el mismo nombre de propiedad
Ejecutar código antes de cada vista
El código que debe ejecutarse antes de que cada vista o página se coloque en el _ViewStart.cshtml
archivo. Por convención, el _ViewStart.cshtml
archivo se encuentra en la carpeta Pages (o Views). Las instrucciones que aparecen en _ViewStart.cshtml
se ejecutan antes de cada vista completa (no los diseños ni las vistas parciales). Al igual que ViewImports.cshtml, _ViewStart.cshtml
es jerárquico. Si un _ViewStart.cshtml
archivo se define en la carpeta view o pages, se ejecutará después del definido en la raíz de la carpeta Pages (o Views) (si existe).
Archivo _ViewStart.cshtml
de ejemplo:
@{
Layout = "_Layout";
}
El archivo anterior especifica que todas las vistas usarán el diseño _Layout.cshtml
.
_ViewStart.cshtml
y _ViewImports.cshtml
no suelen colocarse en la carpeta /Pages/Shared (o /Views/Shared). Las versiones de nivel de aplicación de estos archivos deben colocarse directamente en la carpeta /Pages (o /Views).