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 Razor sintaxis consta de Razor marcado, C# y HTML. Los archivos que contienen Razor generalmente tienen una .cshtml extensión de archivo. Razor también se encuentra en Razor archivos de componentes (.razor). Razor La sintaxis 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 Uso de servicios de JavaScript para crear aplicaciones de página única en ASP.NET Core.

Introducción a la programación web de ASP.NET mediante Razor La sintaxis proporciona muchos ejemplos de programación con Razor sintaxis. 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 Razor es HTML. La representación de HTML a partir del Razor marcado no es diferente de la representación de HTML desde un archivo HTML. El servidor representa el marcado HTML en .cshtmlRazor los archivos 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 un @ símbolo va seguido de una Razor palabra clave reservada, pasa al Razormarcado específico de . De lo contrario, pasa a HTML sin formato.

Para escapar un @ símbolo en Razor el marcado, 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 ejemplo siguiente no se modifican mediante Razor el análisis:

<a href="mailto:Support@contoso.com">Support@contoso.com</a>

Scalable Vector Graphics (SVG)

Se admiten elementos foreignObject svG:

@{
    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 Razor

Las expresiones implícitas Razor comienzan con @ seguidas de código de 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étodos genéricos se deben encapsular en una expresión explícita Razor o en un Razor bloque de código.

Expresiones explícitas Razor

Las expresiones explícitas Razor constan de un @ símbolo con paréntesis equilibrado. Para representar la hora de la semana pasada, se usa el marcado siguiente 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>.

Las expresiones explícitas se pueden usar para representar la salida de métodos genéricos en .cshtml archivos. 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 representa el código HTML siguiente:

&lt;span&gt;Hello World&lt;/span&gt;

El código HTML se muestra en el explorador como texto sin formato:

<span>Hello World</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>

Razor bloques de código

Razor los bloques de código comienzan por @ y se incluyen en {}. 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 Razor página puede volver a 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 debe representar HTML, rodea los caracteres para la representación con la Razor<text> etiqueta :

@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 html o Razor etiqueta, se produce un Razor error en tiempo de ejecución.

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 resto de una línea completa como HTML dentro de un bloque de código, use la sintaxis @::

@for (var i = 0; i < people.Length; i++)
{
    var person = people[i];
    @:Name: @person.Name
}

Sin en @: el código, se genera un Razor error en tiempo de ejecución.

Los caracteres adicionales @ de un Razor archivo pueden provocar errores del compilador en instrucciones más adelante en el bloque . Estos errores de compilador pueden ser difíciles de entender porque el error real se produce antes del error notificado. Este error es habitual después de combinar varias expresiones implícitas/explícitas en un mismo bloque de código.

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;
}

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, se usa el mismo mecanismo para crear asistentes HTML que contengan contenido adicional. En el siguiente código, los asistentes de HTML representan una etiqueta <form> con la instrucción @using:

@using (Html.BeginForm())
{
    <div>
        Email: <input type="email" id="Email" value="">
        <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 secciones críticas con instrucciones lock:

@lock (SomeLock)
{
    // Do critical section work
}

Comentarios

Razor admite comentarios DE C# y HTML:

@{
    /* C# comment */
    // Another C# comment
}
<!-- HTML comment -->

El código representa el siguiente HTML:

<!-- HTML comment -->

Razor El servidor quita los comentarios antes de que se represente la página web. Razor usa @* *@ para 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

Razor Las directivas se representan mediante expresiones implícitas con palabras clave reservadas después del @ símbolo. Normalmente, una directiva cambia la forma en que una vista se analiza, o bien habilita una funcionalidad diferente.

Comprender cómo Razor genera código para una vista facilita la comprensión de 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, la sección Inspeccionar la Razor clase de C# generada para una vista 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]

@code

Este escenario solo se aplica a Razor los componentes (.razor).

El @code bloque permite que un Razor componente agregue miembros de C# (campos, propiedades y métodos) a un componente:

@code {
    // C# members (fields, properties, and methods)
}

En Razor el caso de los componentes, @code es un alias de @functions y se recomienda sobre @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 Razor los componentes, use @code over @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 código siguiente es la clase de C# generada Razor :

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 código siguiente es un tipo de página personalizado 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 _ViewImports.cshtml archivo 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 @inject directiva permite que la Razor página inserte un servicio desde el contenedor de servicios 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 Razor los componentes (.razor).

La @layout directiva especifica un diseño para los componentes enrutables 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 ASP.NET Diseños principalesBlazor.

@model

Este escenario solo se aplica a las vistas y Razor páginas de MVC (.cshtml).

La directiva @model especifica el tipo del modelo que se pasa a una vista o página:

@model TypeNameOfModel

En una aplicación ASP.NET Core MVC o Razor Pages creada con cuentas de usuario individuales, Views/Account/Login.cshtml contiene la siguiente declaración de modelo:

@model LoginViewModel

La clase generada se hereda de RazorPage<dynamic>:

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Razor expone una Model propiedad para acceder al modelo 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 más información, consulte Strongly typed models and the @model keyword.

@namespace

Directiva @namespace:

  • Establece el espacio de nombres de la clase de la página generada Razor , la vista MVC o Razor el componente.
  • Establece los espacios de nombres derivados raíz de las clases de páginas, vistas o componentes del archivo de importaciones más cercano en el árbol de directorios, _ViewImports.cshtml (vistas o páginas) o _Imports.razor (Razor componentes).
@namespace Your.Namespace.Here

Para el Razor ejemplo de 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.
Página 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 la importación de archivos usados con vistas y Razor componentes de MVC.

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 EvenMorePages carpeta del ejemplo anterior tiene un archivo de importación con @namespace Another.Planet (o el Pages/MorePages/EvenMorePages/Page.cshtml archivo contiene @namespace Another.Planet), el resultado se muestra en la tabla siguiente.

Página 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:

@preservewhitespace

Este escenario solo se aplica a Razor los componentes (.razor).

Cuando se establece false en (valor predeterminado), se quita el espacio en blanco del marcado representado de Razor los componentes (.razor) 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.

@section

Este escenario solo se aplica a las vistas y Razor páginas de MVC (.cshtml).

La @section directiva se usa junto con los diseños de MVC y Razor Pages para permitir que las vistas o páginas represente contenido en diferentes partes de la página HTML. Para obtener más información, consulte Diseño 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 Razor los componentes, @using también controla qué componentes están en el ámbito.

Atributos de la directiva

Razor Los atributos de directiva se representan mediante expresiones implícitas con palabras clave reservadas después del @ símbolo. Normalmente, un atributo de directiva cambia la forma en que se analiza un elemento o habilita una funcionalidad diferente.

@attributes

Este escenario solo se aplica a Razor los componentes (.razor).

@attributes permite que un componente represente atributos no declarados. Para más información, vea Componentes Razor de ASP.NET Core.

@bind

Este escenario solo se aplica a Razor los componentes (.razor).

El enlace de datos en los componentes se logra mediante el atributo @bind. Para obtener más información, consulte ASP.NET enlace de datos principalesBlazor.

@bind:culture

Este escenario solo se aplica a Razor los componentes (.razor).

Use el @bind:culture atributo con el @bind atributo para proporcionar un System.Globalization.CultureInfo para analizar y dar formato a un valor. Para más información, vea Globalización y localización de Blazor de ASP.NET Core.

@on{EVENT}

Este escenario solo se aplica a Razor los componentes (.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 Razor los componentes (.razor).

Impide la acción predeterminada para el evento.

@on{EVENT}:stopPropagation

Este escenario solo se aplica a Razor los componentes (.razor).

Detiene la propagación de eventos para el evento.

@key

Este escenario solo se aplica a Razor los componentes (.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 más información, vea Componentes Razor de ASP.NET Core.

@ref

Este escenario solo se aplica a Razor los componentes (.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.

@typeparam

Este escenario solo se aplica a Razor los componentes (.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, vea los siguientes artículos:

@typeparam

Este escenario solo se aplica a Razor los componentes (.razor).

La directiva @typeparam declara un parámetro de tipo genérico para la clase de componente generada:

@typeparam TEntity

Para obtener más información, vea los artículos siguientes:

Delegados con Razor plantilla

Razor Las plantillas permiten definir un fragmento de código de interfaz de usuario con el siguiente formato:

@<tag>...</tag>

En el ejemplo siguiente se muestra cómo especificar un delegado con Razor plantilla 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 puede proporcionar una plantilla insertada Razor como argumento a un método . En el ejemplo siguiente, el Repeat método recibe una Razor plantilla. 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 y Razor páginas de MVC (.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.

Razor palabras clave reservadas

Razor Palabras clave

  • page
  • namespace
  • functions
  • inherits
  • model
  • section
  • helper (Actualmente no es compatible con ASP.NET Core)

Razor Las palabras clave se escapan con @(Razor Keyword) (por ejemplo, @(functions)).

Palabras clave de C# Razor

  • case
  • do
  • default
  • for
  • foreach
  • if
  • else
  • lock
  • switch
  • try
  • catch
  • finally
  • using
  • while

Las palabras clave de C# Razor deben tener un escape doble con @(@C# Razor Keyword) (por ejemplo, @(@case)). El primero @ escapa al Razor analizador. y el segundo @, en el analizador de C#.

Palabras clave reservadas no usadas por Razor

  • class

Inspección de la Razor clase de C# generada para una vista

El Razor SDK controla la compilación de Razor archivos. Al compilar un proyecto, el Razor SDK genera un obj/<build_configuration>/<target_framework_moniker>/Razor directorio en la raíz del proyecto. La estructura de directorios del Razor directorio refleja la estructura de directorios del proyecto.

Tenga en cuenta la siguiente estructura de directorios en un proyecto de ASP.NET Core Razor Pages:

 Areas/
   Admin/
     Pages/
       Index.cshtml
       Index.cshtml.cs
 Pages/
   Shared/
     _Layout.cshtml
   _ViewImports.cshtml
   _ViewStart.cshtml
   Index.cshtml
   Index.cshtml.cs

La creación del proyecto en la configuración de depuración produce el siguiente obj directorio:

 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 Razor motor de vistas realiza búsquedas con distinción entre mayúsculas y minúsculas para las vistas. 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.cshtmly 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.
  • 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 Páginas.

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 usadas por Razor

Las siguientes importaciones las generan las plantillas web de ASP.NET Core para admitir Razor archivos:

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 Razor Sintaxis proporciona muchos ejemplos de programación con Razor sintaxis.