Referencia sobre la sintaxis de Razor para ASP.NET Core
Por Rick Anderson, Taylor Mullen y Dan Vicarel
Razor es una sintaxis de marcado para insertar código basado en .NET en páginas web. La sintaxis de Razor consta de marcado de Razor, C# y HTML. Los archivos que contienen Razor suelen tener la extensión de archivo .cshtml
. Razor también se encuentra en Razor archivos de componentes (.razor
). La sintaxis de Razor es similar a los motores de plantillas de varios marcos de aplicación de página única (SPA) de JavaScript, como Angular, React, VueJs y Svelte. Para obtener más información, consulte Las características descritas en este artículo están obsoletas a partir de ASP.NET Core 3.0.
Introducción a la programación web de ASP.NET mediante la sintaxis de Razor brinda varios ejemplos de programación con la sintaxis de Razor. Aunque el tema se escribió para ASP.NET en lugar de ASP.NET Core, la mayoría de los ejemplos se aplican a ASP.NET Core.
Representación de HTML
El lenguaje predeterminado de Razor es HTML. Representar el HTML del marcado de Razor no difiere mucho de representar el HTML de un archivo HTML. El servidor procesa el marcado HTML en los archivos de .cshtml
Razor sin cambios.
Sintaxis de Razor
Razor admite C# y usa el símbolo @
para realizar la transición de HTML a C#. Razor evalúa las expresiones de C# y las representa en la salida HTML.
Cuando el símbolo @
va seguido de una palabra clave reservada deRazor, realiza una transición a un marcado específico de Razor. En caso contrario, realiza la transición a HTML simple.
Para evitar un símbolo @
en un marcado de Razor, use un segundo símbolo @
:
<p>@@Username</p>
El código aparecerá en HTML con un solo símbolo @
:
<p>@Username</p>
El contenido y los atributos HTML que tienen direcciones de correo electrónico no tratan el símbolo @
como un carácter de transición. Las direcciones de correo electrónico del siguiente ejemplo no se modifican con el análisis de Razor:
<a href="mailto:Support@contoso.com">Support@contoso.com</a>
Scalable Vector Graphics (SVG)
Se admiten elementos SVG foreignObject:
@{
string message = "foreignObject example with Scalable Vector Graphics (SVG)";
}
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" rx="10" ry="10" width="200" height="200" stroke="black"
fill="none" />
<foreignObject x="20" y="20" width="160" height="160">
<p>@message</p>
</foreignObject>
</svg>
Expresiones implícitas de Razor
Las expresiones implícitas de Razor comienzan por @
seguidas del código C#:
<p>@DateTime.Now</p>
<p>@DateTime.IsLeapYear(2016)</p>
Con la excepción de la palabra clave de C# await
, las expresiones implícitas no deben contener espacios. Si la instrucción de C# tiene un final claro, se pueden entremezclar espacios:
<p>@await DoSomething("hello", "world")</p>
Las expresiones implícitas no pueden contener tipos genéricos de C#, ya que los caracteres dentro de los corchetes (<>
) se interpretan como una etiqueta HTML. El siguiente código no es válido:
<p>@GenericMethod<int>()</p>
El código anterior genera un error del compilador similar a uno de los siguientes:
- El elemento "int" no estaba cerrado. Todos los elementos deben ser de autocierre o tener una etiqueta de fin coincidente.
- No se puede convertir el grupo de métodos "GenericMethod" en el tipo no delegado "object". ¿Intentó invocar el método?
Las llamadas a método genéricas deben estar incluidas en una expresión explícita de Razor o en un bloque de código de Razor.
Expresiones explícitas de Razor
Las expresiones explícitas Razor constan de un símbolo @
con un paréntesis que abre y otro que cierra. Para representar la hora de la semana pasada, se usa el siguiente marcado de Razor:
<p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p>
El contenido que haya entre paréntesis @()
se evalúa y se representa en la salida.
Por lo general, las expresiones implícitas (que explicamos en la sección anterior) no pueden contener espacios. En el siguiente código, una semana no se resta de la hora actual:
<p>Last week: @DateTime.Now - TimeSpan.FromDays(7)</p>
El código representa el siguiente HTML:
<p>Last week: 7/7/2016 4:39:52 PM - TimeSpan.FromDays(7)</p>
Se pueden usar expresiones explícitas para concatenar texto con un resultado de la expresión:
@{
var joe = new Person("Joe", 33);
}
<p>Age@(joe.Age)</p>
Sin la expresión explícita, <p>Age@joe.Age</p>
se trataría como una dirección de correo electrónico y se mostraría como <p>Age@joe.Age</p>
. Pero, si se escribe como una expresión explícita, se representa <p>Age33</p>
.
Se pueden usar expresiones explícitas para representar la salida de métodos genéricos en los archivos .cshtml
. En el siguiente marcado se muestra cómo corregir el error mostrado anteriormente provocado por el uso de corchetes en un código C# genérico. El código se escribe como una expresión explícita:
<p>@(GenericMethod<int>())</p>
Codificación de expresiones
Las expresiones de C# que se evalúan como una cadena están codificadas en HTML. Las expresiones de C# que se evalúan como IHtmlContent
se representan directamente a través de IHtmlContent.WriteTo
. Las expresiones de C# que no se evalúan como IHtmlContent
se convierten en una cadena por medio de ToString
y se codifican antes de que se representen.
@("<span>Hello World</span>")
El código anterior genera el siguiente código HTML:
<span>Hello World</span>
El código HTML se muestra en el explorador como texto sin formato:
<span>Hola mundo</span>
La salida de HtmlHelper.Raw
no está codificada, pero se representa como marcado HTML.
Advertencia
Usar HtmlHelper.Raw
en una entrada de usuario no saneada constituye un riesgo de seguridad. Dicha entrada podría contener código JavaScript malintencionado u otras vulnerabilidades de seguridad. Sanear una entrada de usuario es complicado. Evite usar HtmlHelper.Raw
con entradas de usuario.
@Html.Raw("<span>Hello World</span>")
El código representa el siguiente HTML:
<span>Hello World</span>
Bloques de código de Razor
Los bloques de código de Razor comienzan con @
y están encerrados por {}
. A diferencia de las expresiones, el código de C# dentro de los bloques de código no se representa. Las expresiones y los bloques de código de una vista comparten el mismo ámbito y se definen en orden:
@{
var quote = "The future depends on what you do today. - Mahatma Gandhi";
}
<p>@quote</p>
@{
quote = "Hate cannot drive out hate, only love can do that. - Martin Luther King, Jr.";
}
<p>@quote</p>
El código representa el siguiente HTML:
<p>The future depends on what you do today. - Mahatma Gandhi</p>
<p>Hate cannot drive out hate, only love can do that. - Martin Luther King, Jr.</p>
En los bloques de código, declare las funciones locales con marcado para utilizarlas como métodos en la creación de plantillas:
@{
void RenderName(string name)
{
<p>Name: <strong>@name</strong></p>
}
RenderName("Mahatma Gandhi");
RenderName("Martin Luther King, Jr.");
}
El código representa el siguiente HTML:
<p>Name: <strong>Mahatma Gandhi</strong></p>
<p>Name: <strong>Martin Luther King, Jr.</strong></p>
Transiciones implícitas
El lenguaje predeterminado de un bloque de código es C#, pero la página de Razor puede volver al HTML:
@{
var inCSharp = true;
<p>Now in HTML, was in C# @inCSharp</p>
}
Transición delimitada explícita
Para definir una subsección de un bloque de código que deba representar HTML, inserte los caracteres que quiera representar entre etiquetas de Razor<text>
:
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
<text>Name: @person.Name</text>
}
Emplee este método para representar HTML que no esté insertado entre etiquetas HTML. Sin una etiqueta HTML o de Razor, se produce un error de tiempo de ejecución de Razor.
La etiqueta <text>
es útil para controlar el espacio en blanco al representar el contenido:
- Solo se representa el contenido entre etiquetas
<text>
. - En la salida HTML no hay espacios en blanco antes o después de la etiqueta
<text>
.
Transición de línea explícita
Para representar el objeto rest de una línea completa como HTML dentro de un bloque de código, usa la sintaxis @:
:
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
@:Name: @person.Name
}
Sin @:
en el código, se produce un error de tiempo de ejecución de Razor.
Los caracteres @
de más en un archivo de Razor pueden causar errores del compilador en declaraciones posteriores en el bloque. Estos @
errores adicionales del compilador:
- Pueden ser difíciles de entender porque el error real ocurre antes del error informado.
- Es habitual después de combinar varias expresiones implícitas y explícitas en un único bloque de código.
Representación de atributos condicionales
Razor omite automáticamente los atributos que no son necesarios. Si el valor pasado es null
o false
el atributo no se representa.
Por ejemplo, considera el siguiente elemento razor:
<div class="@false">False</div>
<div class="@null">Null</div>
<div class="@("")">Empty</div>
<div class="@("false")">False String</div>
<div class="@("active")">String</div>
<input type="checkbox" checked="@true" name="true" />
<input type="checkbox" checked="@false" name="false" />
<input type="checkbox" checked="@null" name="null" />
El marcado anterior de Razor genera el siguiente código HTML:
<div>False</div>
<div>Null</div>
<div class="">Empty</div>
<div class="false">False String</div>
<div class="active">String</div>
<input type="checkbox" checked="checked" name="true">
<input type="checkbox" name="false">
<input type="checkbox" name="null">
Estructuras de control
Las estructuras de control son una extensión de los bloques de código. Todos los aspectos de los bloques de código (transición a marcado, C# en línea) son válidos también en las siguientes estructuras:
Condicionales @if, else if, else, and @switch
@if
controla cuándo se ejecuta el código:
@if (value % 2 == 0)
{
<p>The value was even.</p>
}
else
y else if
no necesitan el símbolo @
:
@if (value % 2 == 0)
{
<p>The value was even.</p>
}
else if (value >= 1337)
{
<p>The value is large.</p>
}
else
{
<p>The value is odd and small.</p>
}
En el siguiente marcado se muestra cómo usar una instrucción switch:
@switch (value)
{
case 1:
<p>The value is 1!</p>
break;
case 1337:
<p>Your number is 1337!</p>
break;
default:
<p>Your number wasn't 1 or 1337.</p>
break;
}
En bucle @for, @foreach, @while, and @do while
El HTML con plantilla se puede representar con instrucciones de control en bucle. Para representar una lista de personas:
@{
var people = new Person[]
{
new Person("Weston", 33),
new Person("Johnathon", 41),
...
};
}
Se permiten las siguientes instrucciones en bucle:
@for
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
}
@foreach
@foreach (var person in people)
{
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
}
@while
@{ var i = 0; }
@while (i < people.Length)
{
var person = people[i];
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
i++;
}
@do while
@{ var i = 0; }
@do
{
var person = people[i];
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
i++;
} while (i < people.Length);
Instrucción @using
compuesta
En C#, las instrucciones using
se usan para garantizar que un objeto se elimina. En Razor, el mismo mecanismo se emplea para crear asistentes de HTML que incluyen contenido adicional. En el siguiente código, los asistentes de HTML representan una etiqueta <form>
con la instrucción @using
:
@using (Html.BeginForm())
{
<div>
<label>Email: <input type="email" id="Email" value=""></label>
<button>Register</button>
</div>
}
@try, catch, finally
El control de excepciones es similar a C#:
@try
{
throw new InvalidOperationException("You did something invalid.");
}
catch (Exception ex)
{
<p>The exception message: @ex.Message</p>
}
finally
{
<p>The finally statement.</p>
}
@lock
Razor tiene la capacidad de proteger las secciones más importantes con instrucciones de bloqueo:
@lock (SomeLock)
{
// Do critical section work
}
Comentarios
Razor admite comentarios tanto de C# como HTML:
@{
/* C# comment */
// Another C# comment
}
<!-- HTML comment -->
El código representa el siguiente HTML:
<!-- HTML comment -->
El servidor quitará los comentarios de Razor antes de mostrar la página web. Razor usa @* *@
ra delimitar comentarios. El siguiente código está comentado, de modo que el servidor no representa ningún marcado:
@*
@{
/* C# comment */
// Another C# comment
}
<!-- HTML comment -->
*@
Directivas
Las directivas de Razor se representan en las expresiones implícitas con palabras clave reservadas seguidas del símbolo @
. Una directiva suele cambiar la forma en que se compila o funciona una vista.
Conocer el modo en que Razor genera el código de una vista hace que sea más fácil comprender cómo funcionan las directivas.
@{
var quote = "Getting old ain't for wimps! - Anonymous";
}
<div>Quote of the Day: @quote</div>
El código genera una clase similar a la siguiente:
public class _Views_Something_cshtml : RazorPage<dynamic>
{
public override async Task ExecuteAsync()
{
var output = "Getting old ain't for wimps! - Anonymous";
WriteLiteral("/r/n<div>Quote of the Day: ");
Write(output);
WriteLiteral("</div>");
}
}
Más adelante en este artículo, en la sección Inspección de la clase de C# de Razor generada por una vista, se explica cómo ver esta clase generada.
@attribute
La directiva @attribute
agrega el atributo especificado a la clase de la página o vista generada. En el ejemplo siguiente se agrega el atributo [Authorize]
:
@attribute [Authorize]
La directiva @attribute
también se puede usar para proporcionar una plantilla de ruta basada en constantes en un componente de Razor. En el ejemplo siguiente, la directiva @page
de un componente se reemplaza por la directiva @attribute
y la plantilla de ruta basada en constantes en Constants.CounterRoute
, que se establece en otra parte de la aplicación en "/counter
”:
- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]
@code
Este escenario solo se aplica a los componentes de Razor (.razor
).
El bloque @code
habilita un componente de Razor para que agregue miembros de C# (campos, propiedades y métodos) a un componente:
@code {
// C# members (fields, properties, and methods)
}
En el caso de los componentes de Razor, @code
es un alias para @functions
y se recomienda en lugar de @functions
. Se permite emplear más de un bloque @code
.
@functions
La directiva @functions
permite agregar miembros de C# (campos, propiedades y métodos) a la clase generada:
@functions {
// C# members (fields, properties, and methods)
}
En los componentes de Razor, use @code
en lugar de @functions
para agregar miembros de C#.
Por ejemplo:
@functions {
public string GetHello()
{
return "Hello";
}
}
<div>From method: @GetHello()</div>
El código genera el siguiente marcado HTML:
<div>From method: Hello</div>
El siguiente código es la clase C# de Razor generada:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Razor;
public class _Views_Home_Test_cshtml : RazorPage<dynamic>
{
// Functions placed between here
public string GetHello()
{
return "Hello";
}
// And here.
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
WriteLiteral("\r\n<div>From method: ");
Write(GetHello());
WriteLiteral("</div>\r\n");
}
#pragma warning restore 1998
Los métodos @functions
se pueden usar para la creación de plantillas si están marcados:
@{
RenderName("Mahatma Gandhi");
RenderName("Martin Luther King, Jr.");
}
@functions {
private void RenderName(string name)
{
<p>Name: <strong>@name</strong></p>
}
}
El código representa el siguiente HTML:
<p>Name: <strong>Mahatma Gandhi</strong></p>
<p>Name: <strong>Martin Luther King, Jr.</strong></p>
@implements
La directiva @implements
implementa una interfaz para la clase generada.
En el ejemplo siguiente se implementa System.IDisposable para que se pueda llamar al método Dispose:
@implements IDisposable
<h1>Example</h1>
@functions {
private bool _isDisposed;
...
public void Dispose() => _isDisposed = true;
}
@inherits
La directiva @inherits
proporciona control total sobre la clase que la vista hereda:
@inherits TypeNameOfClassToInheritFrom
El siguiente código es un tipo personalizado de página de Razor:
using Microsoft.AspNetCore.Mvc.Razor;
public abstract class CustomRazorPage<TModel> : RazorPage<TModel>
{
public string CustomText { get; } =
"Gardyloo! - A Scottish warning yelled from a window before dumping" +
"a slop bucket on the street below.";
}
CustomText
se muestra en una vista:
@inherits CustomRazorPage<TModel>
<div>Custom text: @CustomText</div>
El código representa el siguiente HTML:
<div>
Custom text: Gardyloo! - A Scottish warning yelled from a window before dumping
a slop bucket on the street below.
</div>
@model
y @inherits
se pueden usar en la misma vista. @inherits
puede estar en un archivo _ViewImports.cshtml
que importa la vista:
@inherits CustomRazorPage<TModel>
El siguiente código es un ejemplo de una vista fuertemente tipada:
@inherits CustomRazorPage<TModel>
<div>The Login Email: @Model.Email</div>
<div>Custom text: @CustomText</div>
Si "rick@contoso.com" se pasa en el modelo, la vista genera el siguiente marcado HTML:
<div>The Login Email: rick@contoso.com</div>
<div>
Custom text: Gardyloo! - A Scottish warning yelled from a window before dumping
a slop bucket on the street below.
</div>
@inject
La directiva @inject
permite a la página de Razor insertar un servicio del contenedor en una vista. Para más información, vea Dependency injection into views (Inserción de dependencias en vistas).
@layout
Este escenario solo se aplica a los componentes de Razor (.razor
).
La directiva @layout
especifica un diseño para los componentes enrutables de Razor que tienen una @page
directiva. Los componentes de diseño se usan para evitar incoherencias y contenido duplicado en el código. Para obtener más información, consulte Diseños de ASP.NET Core Blazor.
@model
Este escenario solo se aplica a las vistas de MVC y a Razor Pages (.cshtml
).
La directiva @model
especifica el tipo del modelo que se pasa a una vista o página:
@model TypeNameOfModel
En una aplicación de ASP.NET Core MVC o de Razor Pages creada con cuentas de usuario individuales, Views/Account/Login.cshtml
contiene la declaración de modelo siguiente:
@model LoginViewModel
La clase generada se hereda de RazorPage<LoginViewModel>
:
public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>
Razor expone una propiedad Model
para tener acceso al modelo que se ha pasado a la vista:
<div>The Login Email: @Model.Email</div>
La directiva @model
especifica el tipo de la propiedad Model
. La directiva especifica el elemento T
en RazorPage<T>
de la clase generada de la que se deriva la vista. Si la directiva @model
no se especifica, la propiedad Model
es de tipo dynamic
. Para obtener más información, vea Strongly typed models and the @model keyword.
@namespace
Directiva @namespace
:
- Establece el espacio de nombres de la clase de la página de Razor, la vista MVC o el componente Razor generado.
- Establece los espacios de nombres de las clases de páginas, vistas o componentes derivados de la raíz del archivo de importaciones más cercano en el árbol de directorios,
_ViewImports.cshtml
(vistas o páginas) o_Imports.razor
(componentes de Razor).
@namespace Your.Namespace.Here
En el ejemplo de Razor Pages que se muestra en la tabla siguiente:
- Cada página importa
Pages/_ViewImports.cshtml
. Pages/_ViewImports.cshtml
contiene@namespace Hello.World
.- Cada página tiene
Hello.World
como raíz de su espacio de nombres.
Page | Espacio de nombres |
---|---|
Pages/Index.cshtml |
Hello.World |
Pages/MorePages/Page.cshtml |
Hello.World.MorePages |
Pages/MorePages/EvenMorePages/Page.cshtml |
Hello.World.MorePages.EvenMorePages |
Las relaciones anteriores se aplican a los archivos de importación usados con las vistas de MVC y los componentes de Razor.
Cuando varios archivos de importación tienen una directiva @namespace
, se usa el archivo más cercano a la página, vista o componente en el árbol de directorios para establecer el espacio de nombres raíz.
Si la carpeta EvenMorePages
del ejemplo anterior tiene un archivo de importaciones con @namespace Another.Planet
(o el archivo Pages/MorePages/EvenMorePages/Page.cshtml
contiene @namespace Another.Planet
), el resultado es el que se muestra en la tabla siguiente.
Page | Espacio de nombres |
---|---|
Pages/Index.cshtml |
Hello.World |
Pages/MorePages/Page.cshtml |
Hello.World.MorePages |
Pages/MorePages/EvenMorePages/Page.cshtml |
Another.Planet |
@page
La directiva @page
tiene efectos diferentes en función del tipo de archivo en el que aparece. Directiva:
- En un archivo
.cshtml
indica que el archivo es una página de Razor. Para obtener más información, consulte Rutas personalizadas y la Introducción a las páginas Razor en ASP.NET Core. - Especifica que un componente de Razor debería controlar la solicitud directamente. Para más información, vea Enrutamiento y navegación de Blazor de ASP.NET Core.
@preservewhitespace
Este escenario solo se aplica a los componentes de Razor (.razor
).
Cuando se establece en false
(valor predeterminado), el espacio en blanco en el marcado representado de los componentes Razor (.razor
) se quita si:
- Está delante o detrás de un elemento.
- Está delante o detrás de un parámetro
RenderFragment
. Por ejemplo, el contenido secundario se pasa a otro componente. - Precede o sigue a un bloque de código de C#, como
@if
o@foreach
.
@rendermode
Este escenario solo se aplica a los componentes de Razor (.razor
).
Establece el modo de representación de un componente Razor:
InteractiveServer
: aplica la representación interactiva del servidor mediante Blazor Server.InteractiveWebAssembly
: : Aplica el renderizado interactivo WebAssembly utilizando Blazor WebAssembly.InteractiveAuto
: Inicialmente aplica el renderizado interactivo de WebAssembly usando Blazor Server, y luego aplica el renderizado interactivo de WebAssembly usando WebAssembly en visitas posteriores luego de descargar el conjunto Blazor.
Para una instancia de componente:
<... @rendermode="InteractiveServer" />
En la definición del componente:
@rendermode InteractiveServer
Nota:
Las plantillas Blazor incluyen una directiva estática using
para RenderMode en el archivo de _Imports
la aplicación (Components/_Imports.razor
) para una sintaxis más corta @rendermode
:
@using static Microsoft.AspNetCore.Components.Web.RenderMode
Sin la directiva anterior, los componentes deben especificar la clase estática RenderMode en la sintaxis @rendermode
explícitamente:
<Dialog @rendermode="RenderMode.InteractiveServer" />
Para obtener más información, incluidas instrucciones sobre cómo deshabilitar la representación previa con el atributo de directiva o directiva, consulte ASP.NET Core Blazor modos de representación.
@section
Este escenario solo se aplica a las vistas de MVC y a Razor Pages (.cshtml
).
La directiva @section
se usa junto con los diseños de MVC y Razor Pages para permitir que las vistas o las páginas representen el contenido en diferentes partes de la página HTML. Para obtener más información, consulte Diseño en ASP.NET Core.
@typeparam
Este escenario solo se aplica a los componentes de Razor (.razor
).
La directiva @typeparam
declara un parámetro de tipo genérico para la clase de componente generada:
@typeparam TEntity
Se admiten los tipos genéricos con restricciones de tipo where
:
@typeparam TEntity where TEntity : IEntity
Para más información, consulte los siguientes artículos.
- Compatibilidad con tipos genéricos de componentes de ASP.NET Core Razor
- Componentes con plantilla de Blazor en ASP.NET Core
@using
La directiva @using
agrega la directiva using
de C# a la vista generada:
@using System.IO
@{
var dir = Directory.GetCurrentDirectory();
}
<p>@dir</p>
En los componentes de Razor, @using
también controla qué componentes están en el ámbito.
Atributos de la directiva
Las directivas de Razor están representadas por las expresiones implícitas con palabras clave reservadas seguidas del símbolo @
. Un atributo de directiva suele cambiar la forma en que se compila o funciona un elemento.
@attributes
Este escenario solo se aplica a los componentes de Razor (.razor
).
@attributes
permite que un componente represente atributos no declarados. Para más información, consulte Parámetros arbitrarios y de expansión de atributos de ASP.NET Core Blazor.
@bind
Este escenario solo se aplica a los componentes de Razor (.razor
).
El enlace de datos en los componentes se logra mediante el atributo @bind
. Para obtener más información, consulte Enlace de datos ASP.NET Core Blazor.
@bind:culture
Este escenario solo se aplica a los componentes de Razor (.razor
).
Use el atributo @bind:culture
con el atributo @bind
para proporcionar un System.Globalization.CultureInfo para analizar y dar formato al valor. Para más información, vea Globalización y localización de Blazor de ASP.NET Core.
@formname
Este escenario solo se aplica a los componentes de Razor (.razor
).
@formname
asigna un nombre de formulario a un formulario HTML sin formato del componente Razor o a un formulario basado en EditForm (Editform
documentación). El valor de @formname
debe ser único, lo que evita colisiones de forma en las situaciones siguientes:
- Un formulario se coloca en un componente con varios formularios.
- Un formulario se origina desde una biblioteca de clases externa, normalmente un paquete NuGet, para un componente con varios formularios y el autor de la aplicación no controla el código fuente de la biblioteca para establecer un nombre de formulario externo diferente al de otro formulario del componente.
Para más información y ejemplos, consulte ASP.NET Core Blazor descripción general de los formularios.
@on{EVENT}
Este escenario solo se aplica a los componentes de Razor (.razor
).
Razor proporciona características de control de eventos para los componentes. Para más información, vea Control de eventos de Blazor en ASP.NET Core.
@on{EVENT}:preventDefault
Este escenario solo se aplica a los componentes de Razor (.razor
).
Impide la acción predeterminada para el evento.
@on{EVENT}:stopPropagation
Este escenario solo se aplica a los componentes de Razor (.razor
).
Detiene la propagación de eventos para el evento.
@key
Este escenario solo se aplica a los componentes de Razor (.razor
).
El atributo de directiva @key
hace que el algoritmo de comparación de componentes garantice la preservación de elementos o componentes en función del valor de la clave. Para obtener más información, consulte Conservar las relaciones entre elementos, componentes y modelos en ASP.NET Core Blazor.
@ref
Este escenario solo se aplica a los componentes de Razor (.razor
).
Las referencias de componentes (@ref
) proporcionan una forma de hacer referencia a la instancia de un componente para poder emitir comandos a dicha instancia. Para más información, vea Componentes Razor de ASP.NET Core.
Delegados de Razor con plantilla
Este escenario solo se aplica a las vistas de MVC y a Razor Pages (.cshtml
).
La plantillas deRazor permiten definir un fragmento de la interfaz de usuario con el formato siguiente:
@<tag>...</tag>
En el ejemplo siguiente se muestra cómo especificar un delegado de Razor como Func<T,TResult>. El tipo dinámico se especifica para el parámetro del método encapsulado por el delegado. Se especifica un tipo de objeto como el valor devuelto del delegado. La plantilla se usa con un elemento List<T> de Pet
que tiene una propiedad Name
.
public class Pet
{
public string Name { get; set; }
}
@{
Func<dynamic, object> petTemplate = @<p>You have a pet named <strong>@item.Name</strong>.</p>;
var pets = new List<Pet>
{
new Pet { Name = "Rin Tin Tin" },
new Pet { Name = "Mr. Bigglesworth" },
new Pet { Name = "K-9" }
};
}
La plantilla se representa con el elemento pets
proporcionado por una instrucción foreach
:
@foreach (var pet in pets)
{
@petTemplate(pet)
}
Salida representada:
<p>You have a pet named <strong>Rin Tin Tin</strong>.</p>
<p>You have a pet named <strong>Mr. Bigglesworth</strong>.</p>
<p>You have a pet named <strong>K-9</strong>.</p>
También se puede proporcionar una plantilla de Razor como un argumneto para un método. En el ejemplo siguiente, el método Repeat
recibe una plantilla de Razor. El método usa la plantilla para generar contenido HTML con repeticiones de elementos proporcionados a partir de una lista:
@using Microsoft.AspNetCore.Html
@functions {
public static IHtmlContent Repeat(IEnumerable<dynamic> items, int times,
Func<dynamic, IHtmlContent> template)
{
var html = new HtmlContentBuilder();
foreach (var item in items)
{
for (var i = 0; i < times; i++)
{
html.AppendHtml(template(item));
}
}
return html;
}
}
Con la lista de mascotas del ejemplo anterior, se llama al método Repeat
con:
- List<T> de
Pet
. - Número de veces que se repite cada mascota.
- Plantilla insertada que se va a usar para los elementos de una lista sin ordenar.
<ul>
@Repeat(pets, 3, @<li>@item.Name</li>)
</ul>
Salida representada:
<ul>
<li>Rin Tin Tin</li>
<li>Rin Tin Tin</li>
<li>Rin Tin Tin</li>
<li>Mr. Bigglesworth</li>
<li>Mr. Bigglesworth</li>
<li>Mr. Bigglesworth</li>
<li>K-9</li>
<li>K-9</li>
<li>K-9</li>
</ul>
Asistentes de etiquetas
Este escenario solo se aplica a las vistas de MVC y a Razor Pages (.cshtml
).
Hay tres directivas que pertenecen a los asistentes de etiquetas.
Directiva | Función |
---|---|
@addTagHelper |
Pone los asistentes de etiquetas a disposición de una vista. |
@removeTagHelper |
Quita los asistentes de etiquetas agregadas anteriormente desde una vista. |
@tagHelperPrefix |
Especifica una cadena de prefijo de etiqueta para permitir la compatibilidad con el asistente de etiquetas y hacer explícito su uso. |
Palabras clave reservadas de Razor
Palabras clave de Razor
page
namespace
functions
inherits
model
section
helper
(no admitida en ASP.NET Core actualmente)
Las palabras clave de Razor se evitan con @(Razor Keyword)
(por ejemplo, @(functions)
).
Palabras clave de C# de Razor
case
do
default
for
foreach
if
else
lock
switch
try
catch
finally
using
while
Las palabras clave C# de Razor deben evitarse dos veces con @(@C# Razor Keyword)
(por ejemplo, @(@case)
). El primer carácter @
evita el analizador de Razor. y el segundo @
, en el analizador de C#.
Palabras clave reservadas no usadas en Razor
class
Inspección de la clase C# de Razor generado para una vista
El Razor SDK controla la compilación de archivos de Razor. De manera predeterminada, no se emiten los archivos de código generados. Para habilitar la emisión de los archivos de código, establezca la directiva EmitCompilerGeneratedFiles
en el archivo de proyecto (.csproj
) a true
:
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
Al compilar un proyecto 6.0 (net6.0
) en la configuración de compilación Debug
, el Razor SDK genera un directorio obj/Debug/net6.0/generated/
en la raíz del proyecto. Su subdirectorio contiene los archivos de código de la página de Razor emitidos.
El Razor SDK controla la compilación de archivos de Razor. Al compilar un proyecto, el Razor SDK genera el directorio obj/{BUILD CONFIGURATION}/{TARGET FRAMEWORK MONIKER}/Razor
en la raíz del proyecto. La estructura de directorios dentro del directorio de Razor
refleja la estructura de directorios del proyecto.
Considere la siguiente estructura de directorios en un proyecto ASP.NET Core Razor Pages 2.1:
Areas/
Admin/
Pages/
Index.cshtml
Index.cshtml.cs
Pages/
Shared/
_Layout.cshtml
_ViewImports.cshtml
_ViewStart.cshtml
Index.cshtml
Index.cshtml.cs
Al compilar el proyecto en la configuración Debug
crea el siguiente directorio obj
:
obj/
Debug/
netcoreapp2.1/
Razor/
Areas/
Admin/
Pages/
Index.g.cshtml.cs
Pages/
Shared/
_Layout.g.cshtml.cs
_ViewImports.g.cshtml.cs
_ViewStart.g.cshtml.cs
Index.g.cshtml.cs
Para ver la clase generada para Pages/Index.cshtml
, abra obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs
.
Búsquedas de vistas y distinción entre mayúsculas y minúsculas
El motor de vista de Razor realiza búsquedas de vistas en las que se distingue entre mayúsculas y minúsculas. Pero la búsqueda real viene determinada por el sistema de archivos subyacente:
- Origen basado en archivos:
- En los sistemas operativos con sistemas de archivos que no distinguen entre mayúsculas y minúsculas (por ejemplo, Windows), las búsquedas de proveedor de archivos físicos no distinguirán mayúsculas de minúsculas. Por ejemplo,
return View("Test")
da como resultado coincidencias para/Views/Home/Test.cshtml
,/Views/home/test.cshtml
y cualquier otra variante de mayúsculas y minúsculas. - En los sistemas de archivos en los que sí se distingue entre mayúsculas y minúsculas (por ejemplo, Linux, OSX y al usar
EmbeddedFileProvider
), las búsquedas distinguirán mayúsculas de minúsculas. Por ejemplo,return View("Test")
coincide específicamente con/Views/Home/Test.cshtml
.
- En los sistemas operativos con sistemas de archivos que no distinguen entre mayúsculas y minúsculas (por ejemplo, Windows), las búsquedas de proveedor de archivos físicos no distinguirán mayúsculas de minúsculas. Por ejemplo,
- Vistas precompiladas: En ASP.NET Core 2.0 y versiones posteriores, las búsquedas de vistas precompiladas no distinguen mayúsculas de minúsculas en todos los sistemas operativos. Este comportamiento es idéntico al comportamiento del proveedor de archivos físicos en Windows. Si dos vistas precompiladas difieren solo por sus mayúsculas o minúsculas, el resultado de la búsqueda será no determinante.
Por tanto, se anima a todos los desarrolladores a intentar que las mayúsculas y minúsculas de los nombres de archivo y de directorio sean las mismas que las mayúsculas y minúsculas de:
- Nombres de acciones, controladores y áreas.
- Razor Pages.
La coincidencia de mayúsculas y minúsculas garantiza que las implementaciones van a encontrar sus vistas, independientemente de cuál sea el sistema de archivos subyacente.
Importaciones utilizadas por Razor
Las siguientes importaciones las generan las plantillas web de ASP.NET Core para admitir archivos de Razor:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
Recursos adicionales
Introducción a la programación web de ASP.NET mediante la sintaxis de Razor brinda varios ejemplos de programación con la sintaxis de Razor.