Razor Referência de sintaxe para ASP.NET Core

Por Rick Anderson, Taylor Mullen e Dan Vicarel

Razor é uma sintaxe de marcação para incorporar um código baseado em .NET em páginas da Web. A sintaxe Razor consiste na marcação Razor, C# e HTML. Os arquivos que contêm Razor geralmente têm uma extensão de arquivo .cshtml. Razor também é encontrado em Razor componente arquivos (.razor). A sintaxe Razor é semelhante aos mecanismos com modelos de várias estruturas de aplicativos de página única (SPA) em JavaScript, como Angular, React, VueJs e Svelte. Para obter mais informações, confira, As funcionalidades descritas neste artigo estão obsoletos desde o ASP.NET Core 3.0.

A Introdução à Programação Web ASP.NET Utilizando a Sintaxe Razor fornece muitos exemplos de programação com a sintaxe Razor. Embora o tópico tenha sido escrito para ASP.NET em vez de ASP.NET Core, a maioria dos exemplos se aplica ao ASP.NET Core.

Renderização de HTML

A linguagem Razor padrão é o HTML. A renderização do HTML a partir da marcação Razor não é diferente da renderização do HTML a partir de um arquivo HTML. A marcação HTML em arquivos .cshtmlRazor é renderizada pelo servidor sem alterações.

Sintaxe de Razor

Razor tem suporte para C# e utiliza o símbolo @ para fazer a transição de HTML para C#. Razor avalia as expressões C# e as renderiza na saída do HTML.

Quando um símbolo @ é seguido por uma palavra-chave reservada Razor, ele passa para uma marcação específica Razor. Caso contrário, a transição será para HTML simples.

Para o escape de um símbolo @ em uma marcação Razor, você deve utilizar um segundo símbolo @:

<p>@@Username</p>

O código é renderizado em HTML com um único símbolo @:

<p>@Username</p>

Conteúdo e atributos HTML que contêm endereços de email não tratam o símbolo @ como um caractere de transição. Os endereços de email no exemplo a seguir não são afetados pela análise Razor:

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

Scalable Vector Graphics (SVG)

SVG Os elementos foreignObject são suportados:

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

Expressões Razor implícitas

As expressões Razor implícitas começam com @ seguido pelo código C#:

<p>@DateTime.Now</p>
<p>@DateTime.IsLeapYear(2016)</p>

Com exceção da palavra-chave C# await, expressões implícitas não devem conter espaços. Se a instrução C# tiver uma terminação clara, espaços podem ser misturados:

<p>@await DoSomething("hello", "world")</p>

Expressões implícitas não podem conter elementos genéricos de C#, pois caracteres dentro de colchetes (<>) são interpretados como uma marca HTML. O código a seguir é inválido:

<p>@GenericMethod<int>()</p>

O código anterior gera um erro de compilador semelhante a um dos seguintes:

  • O elemento "int" não foi fechado. Todos os elementos devem ter fechamento automático ou ter uma marca de fim correspondente.
  • Não é possível converter o grupo de métodos "GenericMethod" em um "object" de tipo não delegado. Você pretendia invocar o método?

As chamadas de métodos genéricos devem ser encapsuladas em uma expressão explícita Razor ou em um bloco de código Razor.

Expressões Razor explícitas

As expressões Razor explícitas consistem em um símbolo @ com parênteses balanceados. Para renderizar a hora da semana passada, utiliza-se a seguinte marcação Razor:

<p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p>

Qualquer conteúdo dentro dos parênteses @() é avaliado e renderizado para a saída.

Expressões implícitas, descritas na seção anterior, geralmente não podem conter espaços. No código a seguir, uma semana não é subtraída da hora atual:

<p>Last week: @DateTime.Now - TimeSpan.FromDays(7)</p>

O código renderiza o HTML a seguir:

<p>Last week: 7/7/2016 4:39:52 PM - TimeSpan.FromDays(7)</p>

Expressões explícitas podem ser usadas para concatenar texto com um resultado de expressão:

@{
    var joe = new Person("Joe", 33);
}

<p>Age@(joe.Age)</p>

Sem a expressão explícita, <p>Age@joe.Age</p> é tratado como um endereço de email e <p>Age@joe.Age</p> é renderizado. Quando escrito como uma expressão explícita, <p>Age33</p> é renderizado.

As expressões explícitas podem ser utilizadas para renderizar a saída de métodos genéricos em arquivos .cshtml. A marcação a seguir mostra como corrigir o erro mostrado anteriormente causado pelos colchetes de um C# genérico. O código é escrito como uma expressão explícita:

<p>@(GenericMethod<int>())</p>

Codificação de expressão

Expressões em C# que são avaliadas como uma cadeia de caracteres estão codificadas em HTML. Expressões em C# que são avaliadas como IHtmlContent são renderizadas diretamente por meio IHtmlContent.WriteTo. Expressões em C# que não são avaliadas como IHtmlContent são convertidas em uma cadeia de caracteres por ToString e codificadas antes que sejam renderizadas.

@("<span>Hello World</span>")

O código anterior renderiza o seguinte HTML:

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

O HTML é mostrado no navegador como texto simples:

<span>Olá, mundo</span>

A saída HtmlHelper.Raw não é codificada, mas renderizada como marcação HTML.

Aviso

Usar HtmlHelper.Raw em uma entrada do usuário que não está limpa é um risco de segurança. A entrada do usuário pode conter JavaScript mal-intencionado ou outras formas de exploração. Limpar a entrada do usuário é difícil. Evite usar HtmlHelper.Raw com a entrada do usuário.

@Html.Raw("<span>Hello World</span>")

O código renderiza o HTML a seguir:

<span>Hello World</span>

Razor blocos de código

Os blocos de código Razor começam com @ e são delimitados por {}. Diferente das expressões, o código C# dentro de blocos de código não é renderizado. Blocos de código e expressões em uma exibição compartilham o mesmo escopo e são definidos em ordem:

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

O código renderiza o HTML a seguir:

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

Em blocos de código, declare funções locais com uma marcação para servir como métodos de modelagem:

@{
    void RenderName(string name)
    {
        <p>Name: <strong>@name</strong></p>
    }

    RenderName("Mahatma Gandhi");
    RenderName("Martin Luther King, Jr.");
}

O código renderiza o HTML a seguir:

<p>Name: <strong>Mahatma Gandhi</strong></p>
<p>Name: <strong>Martin Luther King, Jr.</strong></p>

Transições implícitas

A linguagem padrão em um bloco de código é o C#, mas a página Razor pode fazer a transição de volta para o HTML:

@{
    var inCSharp = true;
    <p>Now in HTML, was in C# @inCSharp</p>
}

Transição delimitada explícita

Para definir uma subseção de um bloco de código que deve renderizar o HTML, envolva os caracteres a serem renderizados com a marca Razor<text>:

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

Use essa abordagem para renderizar HTML que não está circundado por uma marca HTML. Se você não tiver uma marca HTML ou Razor, ocorrerá um erro de runtime Razor.

A marca <text> é útil para controlar o espaço em branco ao renderizar conteúdo:

  • Somente o conteúdo entre a marca <text> é renderizado.
  • Não aparece nenhum espaço em branco antes ou depois da marca <text> na saída HTML.

Transição explícita de linha

Para renderizar o rest de uma linha inteira como HTML dentro de um bloco de códigos, use a sintaxe @::

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

Sem o @: no código, você receberá um erro de runtime Razor.

Caracteres @ extras em um arquivo Razor podem causar erros no compilador em instruções posteriores do bloco. Esses erros extras do compilador @:

  • Podem ser difíceis de entender porque o erro real ocorre antes do erro relatado.
  • São comuns após a combinação de várias expressões implícitas e explícitas em um único bloco de código.

Atributo condicional renderizado

Razor omite automaticamente os atributos que não são necessários. Se o valor passado for null ou false, o atributo não será renderizado.

Por exemplo, considere o seguinte 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" />

A marcação Razor anterior gera o seguinte 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">

Estruturas de controle

Estruturas de controle são uma extensão dos blocos de código. Todos os aspectos dos blocos de código (transição para marcação, C# embutido) também se aplicam às seguintes estruturas:

Condicionais @if, else if, else, and @switch

@if controla quando o código é executado:

@if (value % 2 == 0)
{
    <p>The value was even.</p>
}

else e else if não exigem o 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>
}

A marcação a seguir mostra como usar uma instrução 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;
}

Looping @for, @foreach, @while, and @do while

O HTML no modelo pode ser renderizado com instruções de controle em loop. Para renderizar uma lista de pessoas:

@{
    var people = new Person[]
    {
          new Person("Weston", 33),
          new Person("Johnathon", 41),
          ...
    };
}

Há suporte para as seguintes instruções em loop:

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

@using composto

Em C#, uma instrução using é usada para garantir que um objeto seja descartado. Em Razor, o mesmo mecanismo é utilizado para criar Auxiliadores HTML que contêm conteúdo adicional. No código a seguir, os Auxiliares HTML renderizam uma marca <form> com a instrução @using:

@using (Html.BeginForm())
{
    <div>
        <label>Email: <input type="email" id="Email" value=""></label>
        <button>Register</button>
    </div>
}

@try, catch, finally

O tratamento de exceções é semelhante ao de 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 tem a capacidade de proteger seções críticas com instruções de bloqueio:

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

Comentários

Razor suporta comentários em C# e HTML:

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

O código renderiza o HTML a seguir:

<!-- HTML comment -->

Razor os comentários são removidos pelo servidor antes que a página da Web seja renderizada. Razor utiliza @* *@ para delimitar comentários. O código a seguir é comentado, de modo que o servidor não renderiza nenhuma marcação:

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

Diretivas

As diretivas Razor são representadas por expressões implícitas com palavras-chave reservadas após o símbolo @. Uma diretiva normalmente altera a maneira como uma visualização é compilada ou funciona.

Se você entender como Razor gera código para uma exibição, será mais fácil entender como as diretivas funcionam.

@{
    var quote = "Getting old ain't for wimps! - Anonymous";
}

<div>Quote of the Day: @quote</div>

O código gera uma classe semelhante à seguinte:

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

Mais adiante neste artigo, a seção Inspecionar a classe C# Razor gerada para uma exibição explica como você pode exibir essa classe gerada.

@attribute

A diretiva @attribute adiciona o atributo fornecido à classe da página ou exibição gerada. O exemplo a seguir adiciona o atributo [Authorize]:

@attribute [Authorize]

A diretiva @attribute também pode ser utilizada para fornecer um modelo de rota baseado em constante em um componente Razor. No exemplo a seguir, a diretiva @page em um componente é substituída pela diretiva @attribute e pelo modelo de rota baseado em constante em Constants.CounterRoute, que é definido em outro lugar no aplicativo como "/counter":

- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]

@code

Esse cenário se aplica apenas aos componentes Razor (.razor).

O bloco @code habilita um componente Razor para que você adicione os membros do C# (campos, propriedades e métodos) a um componente:

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

Para os componentes Razor, @code é um alias de @functions e recomendado em relação a @functions. Mais de um bloco de @code é permitido.

@functions

A diretiva @functions permite adicionar membros (campos, propriedades e métodos) de C# à classe gerada:

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

Nos componentes Razor, utilize @code em vez de @functions para adicionar membros do C#.

Por exemplo:

@functions {
    public string GetHello()
    {
        return "Hello";
    }
}

<div>From method: @GetHello()</div> 

O código gera a seguinte marcação HTML:

<div>From method: Hello</div>

O código a seguir é a classe C# Razor gerada:

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

Os métodos @functions servem como métodos de modelagem quando têm uma marcação:

@{
    RenderName("Mahatma Gandhi");
    RenderName("Martin Luther King, Jr.");
}

@functions {
    private void RenderName(string name)
    {
        <p>Name: <strong>@name</strong></p>
    }
}

O código renderiza o HTML a seguir:

<p>Name: <strong>Mahatma Gandhi</strong></p>
<p>Name: <strong>Martin Luther King, Jr.</strong></p>

@implements

A diretiva @implements implementa uma interface para a classe gerada.

O exemplo a seguir implementa System.IDisposable para que o método Dispose possa ser chamado:

@implements IDisposable

<h1>Example</h1>

@functions {
    private bool _isDisposed;

    ...

    public void Dispose() => _isDisposed = true;
}

@inherits

A diretiva @inherits fornece controle total da classe que a exibição herda:

@inherits TypeNameOfClassToInheritFrom

O código a seguir é um tipo de página Razor personalizada:

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

O CustomText é exibido em uma exibição:

@inherits CustomRazorPage<TModel>

<div>Custom text: @CustomText</div>

O código renderiza o HTML a seguir:

<div>
    Custom text: Gardyloo! - A Scottish warning yelled from a window before dumping
    a slop bucket on the street below.
</div>

@model e @inherits podem ser usados na mesma exibição. @inherits pode estar em um arquivo _ViewImports.cshtml que a exibição importa:

@inherits CustomRazorPage<TModel>

O código a seguir é um exemplo de exibição fortemente tipada:

@inherits CustomRazorPage<TModel>

<div>The Login Email: @Model.Email</div>
<div>Custom text: @CustomText</div>

Se "rick@contoso.com" for passado no modelo, a exibição gerará a seguinte marcação 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

A diretiva @inject habilita o Razor Page para injetar um serviço do serviço de contêiner em uma exibição. Para obter mais informações, consulte Injeção de dependência em exibições.

@layout

Esse cenário se aplica apenas aos componentes Razor (.razor).

A diretiva @layout especifica um layout para componentes Razor roteáveis que tenham uma diretiva @page. Os componentes de layout são usados para evitar casos de duplicação e inconsistência no código. Para obter mais informações, confira os layouts ASP.NET Core Blazor.

@model

Esse cenário se aplica apenas a exibições do MVC e Razor Pages (.cshtml).

A diretiva @model especifica o tipo do modelo passado para uma exibição ou página:

@model TypeNameOfModel

Em um aplicativo MVC do ASP.NET Core ou Razor Pages criado com contas de usuário individuais, Views/Account/Login.cshtml contém a seguinte declaração de modelo:

@model LoginViewModel

A classe gerada herda de RazorPage<LoginViewModel>:

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Razor expõe uma propriedade Model para que você possa acessar o modelo passado para a exibição:

<div>The Login Email: @Model.Email</div>

A diretiva @model especifica o tipo da propriedade Model. A diretiva especifica o T em RazorPage<T> da classe gerada da qual a exibição deriva. Se a diretiva @model não for especificada, a propriedade Model será do tipo dynamic. Para obter mais informações, consulte Strongly typed models and the @model keyword.

@namespace

A diretiva @namespace:

  • Define o namespace da classe da página Razor gerada, da exibição do MVC ou do componente Razor.
  • Define os namespaces derivados da raiz das classes de páginas, exibições ou componentes do arquivo de importação mais próximo na árvore de diretórios, _ViewImports.cshtml (exibições ou páginas) ou _Imports.razor (componentes Razor).
@namespace Your.Namespace.Here

Para o exemplo do Razor Pages mostrado na tabela a seguir:

  • Cada página importa Pages/_ViewImports.cshtml.
  • Pages/_ViewImports.cshtml contém @namespace Hello.World.
  • Cada página tem Hello.World como a raiz do namespace.
? Namespace
Pages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml Hello.World.MorePages.EvenMorePages

As relações anteriores se aplicam aos arquivos de importação utilizados com componentes Razor e exibições do MVC.

Quando vários arquivos de importação têm uma diretiva @namespace, o arquivo mais próximo da página, exibição ou componente na árvore de diretórios é usado para definir o namespace raiz.

Se a pasta EvenMorePages do exemplo anterior tiver um arquivo de importação com @namespace Another.Planet (ou o arquivo Pages/MorePages/EvenMorePages/Page.cshtml contiver @namespace Another.Planet), o resultado será mostrado na tabela a seguir.

? Namespace
Pages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml Another.Planet

@page

A diretiva @page tem efeitos diferentes dependendo do tipo do arquivo em que aparece. A diretiva:

@preservewhitespace

Esse cenário se aplica apenas aos componentes Razor (.razor).

Quando definido como false (padrão), os espaços em branco na marcação renderizada de componentes Razor (.razor) serão removidos se:

  • Estiver à esquerda ou à direita dentro de um elemento.
  • Estiver à esquerda ou à direita dentro de um parâmetro RenderFragment. Por exemplo, conteúdo filho passado para outro componente.
  • Preceder ou seguir um bloco de código C#, como @if ou @foreach.

@rendermode

Esse cenário se aplica apenas aos componentes Razor (.razor).

Define o modo de renderização de um componente Razor:

  • InteractiveServer: aplica a renderização interativa do servidor usando Blazor Server.
  • InteractiveWebAssembly: aplica a renderização interativa do WebAssembly usando Blazor WebAssembly.
  • InteractiveAuto: inicialmente aplica a renderização interativa do WebAssembly usando Blazor Servere aplica a renderização interativa do WebAssembly usando WebAssembly em visitas subsequentes depois que o pacote Blazor é baixado.

Para uma instância de componente:

<... @rendermode="InteractiveServer" />

Na definição do componente:

@rendermode InteractiveServer

Observação

Os modelos do Blazor incluem uma diretiva estática using para RenderMode no arquivo _Imports do aplicativo (Components/_Imports.razor) para sintaxe mais curta @rendermode:

@using static Microsoft.AspNetCore.Components.Web.RenderMode

Sem a diretiva anterior, os componentes devem especificar a classe estática RenderMode na sintaxe @rendermode explicitamente:

<Dialog @rendermode="RenderMode.InteractiveServer" />

Para obter mais informações, incluindo diretrizes sobre como desabilitar a pré-renderização com o atributo directive/directive, consulte Modos de renderização do ASP.NET Core Blazor.

@section

Esse cenário se aplica apenas a exibições do MVC e Razor Pages (.cshtml).

A diretiva @section é utilizada em conjunto com o MVC e Razor Layouts de páginas para habilitar exibições ou páginas para renderizar conteúdo em diferentes partes da página HTML. Saiba mais em Layout no ASP.NET Core.

@typeparam

Esse cenário se aplica apenas aos componentes Razor (.razor).

A diretiva @typeparam declara um parâmetro de tipo genérico para a classe de componente gerada:

@typeparam TEntity

Tipos genéricos com restrições de tipo where são suportados:

@typeparam TEntity where TEntity : IEntity

Para obter mais informações, consulte os seguintes artigos:

@using

A diretiva @using adiciona a diretiva using de C# à exibição gerada:

@using System.IO
@{
    var dir = Directory.GetCurrentDirectory();
}
<p>@dir</p>

Nos componentes Razor, @using também controla quais componentes estão no escopo.

Atributos de diretiva

Os atributos da diretiva Razor são representados por expressões implícitas com palavras-chave reservadas após o símbolo @. Um atributo de diretiva normalmente altera a maneira como um elemento é compilado ou funciona.

@attributes

Esse cenário se aplica apenas aos componentes Razor (.razor).

@attributes permite que um componente renderize atributos não declarados. Para obter mais informações, confira Nivelamento de atributos Blazor do ASP.NET Core e parâmetros arbitrários.

@bind

Esse cenário se aplica apenas aos componentes Razor (.razor).

A vinculação de dados nos componentes é realizada com o atributo @bind. Para obter mais informações, confira Associação de dados Blazor do ASP.NET Core.

@bind:culture

Esse cenário se aplica apenas aos componentes Razor (.razor).

Utilize o atributo @bind:culture com o atributo @bind para fornecer um System.Globalization.CultureInfo para a análise e formatação de um valor. Para obter mais informações, confira Globalização e localização Blazor do ASP.NET Core.

@formname

Esse cenário se aplica apenas aos componentes Razor (.razor).

@formname atribui um nome de formulário ao formulário HTML simples de um componente Razor ou a um formulário baseado em EditForm (documentação Editform). O valor de @formname deve ser exclusivo, o que impede conflitos de formulário nas seguintes situações:

  • Um formulário é colocado em um componente com vários formulários.
  • Um formulário é originado de uma biblioteca de classes externa, geralmente um pacote NuGet, para um componente com vários formulários, e o autor do aplicativo não controla o código-fonte da biblioteca para definir um nome de formulário externo diferente de um nome usado por outro formulário no componente.

Para obter mais informações e exemplos, confira Visão geral de formulários Blazor no ASP.NET Core.

@on{EVENT}

Esse cenário se aplica apenas aos componentes Razor (.razor).

Razor fornece recursos de manipulação de eventos para componentes. Para saber mais, confira Tratamento de eventos do Blazor no ASP.NET Core.

@on{EVENT}:preventDefault

Esse cenário se aplica apenas aos componentes Razor (.razor).

Impede a ação padrão do evento.

@on{EVENT}:stopPropagation

Esse cenário se aplica apenas aos componentes Razor (.razor).

Interrompe a propagação do evento para o evento.

@key

Esse cenário se aplica apenas aos componentes Razor (.razor).

O atributo da diretiva @key faz com que os componentes comparem o algoritmo para garantir a preservação de elementos ou componentes com base no valor da chave. Para obter mais informações, confira Retenção de relações de elementos, componentes e modelos no ASP.NET Core Blazor.

@ref

Esse cenário se aplica apenas aos componentes Razor (.razor).

Referências de componente (@ref) proporcionam uma maneira de fazer referência a uma instância de componente para que você possa emitir comandos para essa instância. Para saber mais, confira Componentes Razor do ASP.NET Core.

Representantes Razor com modelo

Esse cenário se aplica apenas a exibições do MVC e Razor Pages (.cshtml).

Razor modelos permitem que você defina um snippet da interface do usuário com o seguinte formato:

@<tag>...</tag>

O exemplo a seguir ilustra como você pode especificar um representante Razor com modelo como Func<T,TResult>. O tipo dinâmico é especificado para o parâmetro do método encapsulado pelo delegado. Um tipo de objeto é especificado como o valor retornado do delegado. O modelo é usado com uma List<T> de Pet que tem uma propriedade 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" }
    };
}

O modelo é renderizado com pets fornecido por uma instrução foreach:

@foreach (var pet in pets)
{
    @petTemplate(pet)
}

Saída renderizada:

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

Você também pode fornecer um modelo Razor em linha como o argumento de um método. No exemplo a seguir, o método Repeat recebe um modelo Razor. O método usa o modelo para produzir o conteúdo HTML com repetições de itens fornecidos em uma 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;
    }
}

Usando a lista de animais de estimação do exemplo anterior, o método Repeat é chamado com:

  • List<T> de Pet.
  • Número de vezes que deve ser repetido cada animal de estimação.
  • Modelo embutido a ser usado para os itens da lista de uma lista não ordenada.
<ul>
    @Repeat(pets, 3, @<li>@item.Name</li>)
</ul>

Saída renderizada:

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

Auxiliares de Marca

Esse cenário se aplica apenas a exibições do MVC e Razor Pages (.cshtml).

Há três diretivas que relacionadas aos Auxiliares de marca.

Diretiva Função
@addTagHelper Disponibiliza os Auxiliares de marca para uma exibição.
@removeTagHelper Remove os Auxiliares de marca adicionados anteriormente de uma exibição.
@tagHelperPrefix Especifica um prefixo de marca para habilitar o suporte do Auxiliar de marca e tornar explícito o uso do Auxiliar de marca.

Razor palavras-chave reservadas

Razor palavras-chave

  • page
  • namespace
  • functions
  • inherits
  • model
  • section
  • helper (atualmente não é suportado com o ASP.NET Core)

As palavras-chave Razor estão com escape @(Razor Keyword) (por exemplo, @(functions)).

Palavras-chave Razor do C#

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

As palavras-chave Razor do C# devem ter duplo escape com @(@C# Razor Keyword) (por exemplo, @(@case)). O primeiro com escape @ do analisador Razor. O segundo @ faz o escape do analisador C#.

Palavras-chave reservadas não utilizadas por Razor

  • class

Inspecione a classe C# Razor gerada para uma exibição

O Razor SDK lida com a compilação de Razor arquivos. Por padrão, os arquivos de código gerados não são emitidos. Para habilitar a emissão dos arquivos de código, defina a diretiva EmitCompilerGeneratedFiles no arquivo do projeto (.csproj) como true:

<PropertyGroup>
  <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

Ao criar um projeto 6.0 (net6.0) na configuração da compilação Debug, o SDK Razor gera um diretório obj/Debug/net6.0/generated/ na raiz do projeto. Seu subdiretório contém os arquivos de código da página Razor emitidos.

O Razor SDK lida com a compilação de Razor arquivos. Ao criar um projeto, o SDK Razor gera um diretório obj/{BUILD CONFIGURATION}/{TARGET FRAMEWORK MONIKER}/Razor na raiz do projeto. A estrutura de diretórios dentro do diretório Razor reflete a estrutura de diretórios do projeto.

Considere a seguinte estrutura de diretórios em um projeto 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

Ao criar o projeto na configuração Debug, você obtém o seguinte diretório 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 exibir a classe gerada para Pages/Index.cshtml, abra obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs.

Pesquisas de exibição e diferenciação de maiúsculas e minúsculas

O mecanismo de exibição Razor realiza pesquisas que diferenciam maiúsculas de minúsculas nas exibições. No entanto, a pesquisa real é determinada pelo sistema de arquivos subjacente:

  • Origem baseada em arquivo:
    • Em sistemas operacionais com sistemas de arquivos que não diferenciam maiúsculas e minúsculas (por exemplo, Windows), pesquisas no provedor de arquivos físico não diferenciam maiúsculas de minúsculas. Por exemplo, return View("Test") resulta na correspondência de /Views/Home/Test.cshtml, /Views/home/test.cshtml e qualquer outra variante de maiúsculas e minúsculas.
    • Em sistemas de arquivos que diferenciam maiúsculas de minúsculas (por exemplo, Linux, OSX e com EmbeddedFileProvider), as pesquisas diferenciam maiúsculas de minúsculas. Por exemplo, return View("Test") corresponde especificamente a /Views/Home/Test.cshtml.
  • Exibições pré-compiladas: com o ASP.NET Core 2.0 e posteriores, pesquisar em exibições pré-compiladas não diferencia maiúsculas de minúsculas em nenhum sistema operacional. O comportamento é idêntico ao comportamento do provedor de arquivos físico no Windows. Se duas exibições pré-compiladas diferirem apenas quanto ao padrão de maiúsculas e minúsculas, o resultado da pesquisa não será determinístico.

Os desenvolvedores são incentivados a fazer a correspondência entre as maiúsculas e minúsculas dos nomes dos arquivos e de diretórios com o uso de maiúsculas e minúsculas em:

  • Nomes de área, controlador e ação.
  • Razor Pages.

Fazer essa correspondência garante que as implantações encontrem suas exibições, independentemente do sistema de arquivos subjacente.

Importações utilizadas por Razor

As seguintes importações foram geradas pelos modelos da Web do ASP.NET Core para suportar os Arquivos 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 adicionais

A Introdução à Programação Web ASP.NET Utilizando a Sintaxe Razor fornece muitos exemplos de programação com a sintaxe Razor.