RazorInformazioni di riferimento sulla sintassi ASP.NET Core

Di Rick Anderson, Taylor Mullene Dan Vicarel

Razor è una sintassi di markup per l'incorporamento di codice basato su .NET nelle pagine Web. La Razor sintassi è Razor costituita da markup, C# e HTML. I file Razor contenenti in genere hanno un'estensione .cshtml di file. Razorè disponibile anche nei Razor file dei componenti ( .razor ). RazorLa sintassi è simile ai motori di modelli di vari framework di applicazione a pagina singola (SPA) JavaScript, ad esempio Angular, React, VueJs e Svelte. Per altre informazioni, vedere Usare i servizi JavaScript per creare applicazioni a pagina singola in ASP.NET Core.

Rendering di HTML

La lingua Razor predefinita è HTML. Il rendering del codice HTML Razor dal markup non è diverso dal rendering del codice HTML da un file HTML. Il rendering del markup HTML .cshtml Razor nei file viene eseguito dal server senza modifiche.

Sintassi Razor

Razor supporta C# e usa il @ simbolo per la transizione da HTML a C#. Razor valuta le espressioni C# e le esegue il rendering nell'output HTML.

Quando un @ simbolo è seguito da una parola chiave Razor riservata,esegue la transizione nel markup Razor specifico. In caso contrario, esegue la transizione in codice HTML normale.

Per eseguire @ l'escape di un simbolo nel Razor markup, usare un secondo @ simbolo:

<p>@@Username</p>

Il rendering del codice viene eseguito in HTML con un solo simbolo @:

<p>@Username</p>

Gli attributi e il contenuto HTML contenenti indirizzi di posta elettronica non considerano il simbolo @ come un carattere di transizione. Gli indirizzi di posta elettronica nell'esempio seguente non vengono toccati Razor dall'analisi:

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

Scalable Vector Graphics (SVG)

Gli elementi foreignObject SVG sono supportati:

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

Espressioni Razor implicite

Le Razor espressioni implicite @ iniziano con seguite dal codice C#:

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

Fatta eccezione per la parola chiave await di C#, le espressioni implicite non devono contenere spazi. Se l'istruzione C# ha una fine chiaramente definita, possono coesistere spazi:

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

Le espressioni implicite non possono contenere generics C#, poiché i caratteri all'interno delle parentesi (<>) vengono interpretati come un tag HTML. Il codice seguente non è valido:

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

Il codice precedente genera un errore del compilatore simile a uno dei seguenti:

  • L'elemento "int" non è stato chiuso. Tutti gli elementi devono essere a chiusura automatica o avere un tag di fine corrispondente.
  • Non è possibile convertire il gruppo di metodi 'GenericMethod' nel tipo non delegato 'object'. Si intendeva chiamare il metodo?'

Le chiamate al metodo generico devono essere incapsulate in un'espressione Razor esplicita o in un Razor blocco di codice.

Espressioni Razor esplicite

Le Razor espressioni esplicite sono @ costituite da un simbolo con parentesi bilanciate. Per eseguire il rendering dell'ora della settimana precedente, viene Razor usato il markup seguente:

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

Qualsiasi contenuto all'interno delle parentesi @() viene valutato e sottoposto a rendering nell'output.

Le espressioni implicite, descritte nella sezione precedente, in genere non possono contenere spazi. Nel codice seguente, una settimana non viene sottratta dall'ora corrente:

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

Il codice esegue il rendering dell'HTML seguente:

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

È possibile usare le espressioni esplicite per concatenare testo con un risultato dell'espressione:

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

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

Senza l'espressione esplicita, <p>Age@joe.Age</p> viene considerato come un indirizzo di posta elettronica e <p>Age@joe.Age</p> viene sottoposto a rendering. Se viene scritto come espressione esplicita, <p>Age33</p> viene sottoposto a rendering.

Le espressioni esplicite possono essere usate per eseguire il rendering dell'output dai metodi generici nei .cshtml file. Il markup seguente illustra come correggere l'errore riportato in precedenza, causato dalle parentesi quadre di un oggetto generico C#. Il codice viene scritto come un'espressione esplicita:

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

Codifica di espressioni

Le espressioni C# che restituiscono una stringa sono codificate in HTML. Le espressioni C# che restituiscono IHtmlContent vengono sottoposte a rendering direttamente tramite IHtmlContent.WriteTo. Le espressioni C# che non restituiscono IHtmlContent vengono convertite in una stringa da ToString e codificate prima di essere sottoposte a rendering.

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

Il codice precedente esegue il rendering del codice HTML seguente:

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

Il codice HTML viene visualizzato nel browser come testo normale:

<span > Hello World < /span>

L'output HtmlHelper.Raw non è codificato ma viene sottoposto a rendering come markup HTML.

Avviso

L'uso di HtmlHelper.Raw su input utente non purificato costituisce un rischio per la sicurezza. L'input utente potrebbe contenere JavaScript dannoso o altri attacchi. La purificazione degli input utente è difficile. Evitare l'uso di HtmlHelper.Raw con l'input utente.

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

Il codice esegue il rendering dell'HTML seguente:

<span>Hello World</span>

Razor blocchi di codice

Razor I blocchi di codice @ iniziano con e sono racchiusi tra {} . A differenza delle espressioni, il codice C# all'interno di blocchi di codice non viene sottoposto a rendering. I blocchi di codice e le espressioni in una visualizzazione condividono lo stesso ambito e vengono definiti in ordine:

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

Il codice esegue il rendering dell'HTML seguente:

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

Nei blocchi di codice dichiarare funzioni locali con markup da usare come metodi per la creazione di modelli:

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

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

Il codice esegue il rendering dell'HTML seguente:

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

Transizioni implicite

Il linguaggio predefinito in un blocco di codice è C#, ma Razor la pagina può tornare a HTML:

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

Transizione esplicita delimitata

Per definire una sottosezione di un blocco di codice che deve eseguire il rendering del codice HTML, racchiudere i caratteri per il rendering con il Razor <text> tag :

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

Usare questo approccio per eseguire il rendering di HTML che non è racchiuso tra tag HTML. Senza codice HTML o Razor tag, si verifica un Razor errore di runtime.

Il tag <text> è utile per controllare gli spazi vuoti durante il rendering del contenuto:

  • Solo il contenuto all'interno del tag <text> viene sottoposto a rendering.
  • Non vengono visualizzati spazi vuoti prima o dopo il tag <text> nell'output HTML.

Transizione di riga esplicita

Per eseguire il rendering del resto di un'intera riga come HTML all'interno di un blocco di codice, usare la @: sintassi:

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

Senza nel @: codice, viene generato un Razor errore di runtime.

I @ caratteri aggiuntivi in un file possono causare errori del Razor compilatore nelle istruzioni successive nel blocco . Questi errori del compilatore possono essere difficili da comprendere perché l'errore effettivo si verifica prima dell'errore segnalato. Questo errore è comune dopo la combinazione di più espressioni implicite/esplicite in un singolo blocco di codice.

Strutture di controllo

Le strutture di controllo sono un'estensione dei blocchi di codice. Tutti gli aspetti dei blocchi di codice (transizione al markup, C# inline) sono validi anche per le strutture seguenti:

Condizionali @if, else if, else, and @switch

@if controlla quando viene eseguito il codice:

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

else e else if non richiedono il simbolo @:

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

Nel markup seguente viene illustrato come usare un'istruzione 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;
}

Loop @for, @foreach, @while, and @do while

È possibile eseguire il rendering di HTML basato su modelli con le istruzioni di controllo ciclo. Per eseguire il rendering di un elenco di persone:

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

Sono supportate le seguenti istruzioni di ciclo:

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

Istruzione @using composita

In C# viene usata un'istruzione using per verificare che un oggetto sia stato eliminato. In Razor viene usato lo stesso meccanismo per creare helper HTML che contengono contenuto aggiuntivo. Nel codice seguente gli helper HTML eseguono il rendering di un tag <form> con l'istruzione @using:

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

@try, catch, finally

La gestione delle eccezioni è simile 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 è in grado di proteggere le sezioni critiche con istruzioni di blocco:

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

Commenti

Razor supporta i commenti C# e HTML:

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

Il codice esegue il rendering dell'HTML seguente:

<!-- HTML comment -->

Razor I commenti vengono rimossi dal server prima del rendering della pagina Web. Razor usa @* *@ per delimitare i commenti. Il codice seguente è commentato, pertanto il server non esegue il rendering di alcun markup:

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

Direttive

Razor Le direttive sono rappresentate da espressioni implicite con parole chiave riservate che segue il @ simbolo . Una direttiva cambia in genere il modo in cui viene analizzata una visualizzazione o abilita funzionalità diverse.

La comprensione Razor del modo in cui genera codice per una vista semplifica la comprensione del funzionamento delle direttive.

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

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

Il codice genera una classe simile alla seguente:

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

Più avanti in questo articolo, la sezione Esaminare la Razor classe C# generata per una vista illustra come visualizzare questa classe generata.

@attribute

La direttiva @attribute aggiunge l'attributo specificato alla classe della pagina o della visualizzazione generata. L'esempio seguente aggiunge l'attributo [Authorize]:

@attribute [Authorize]

@code

Questo scenario si applica solo Razor ai componenti ( .razor ).

Il @code blocco consente a un Razor componente di aggiungere membri C# (campi, proprietà e metodi) a un componente:

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

Per Razor i componenti, @code è un alias di e consigliato rispetto a @functions @functions . È consentito più di un blocco @code.

@functions

La direttiva @functions consente di aggiungere membri C# (campi, proprietà e metodi) alla classe generata:

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

Nei Razor componentiusare @code over per aggiungere membri @functions C#.

Ad esempio:

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

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

Il codice genera il markup HTML seguente:

<div>From method: Hello</div>

Il codice seguente è la classe Razor C# generata:

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

I metodi @functions fungono da metodi per la creazione di modelli quando includono markup:

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

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

Il codice esegue il rendering dell'HTML seguente:

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

@implements

La direttiva @implements implementa un'interfaccia per la classe generata.

L'esempio seguente implementa System.IDisposable in modo che sia possibile chiamare il metodo Dispose:

@implements IDisposable

<h1>Example</h1>

@functions {
    private bool _isDisposed;

    ...

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

@inherits

La direttiva @inherits offre il controllo completo della classe che viene ereditata dalla visualizzazione:

@inherits TypeNameOfClassToInheritFrom

Il codice seguente è un tipo Razor di pagina personalizzato:

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

L'elemento CustomText viene inserito in una visualizzazione:

@inherits CustomRazorPage<TModel>

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

Il codice esegue il rendering dell'HTML seguente:

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

È possibile usare @model e @inherits nella stessa visualizzazione. @inherits può essere in un _ViewImports.cshtml file importato dalla vista:

@inherits CustomRazorPage<TModel>

Il codice seguente è un esempio di visualizzazione fortemente tipizzata:

@inherits CustomRazorPage<TModel>

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

Se "rick@contoso.com" viene passato nel modello, la visualizzazione genera il markup HTML seguente:

<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 direttiva consente alla pagina di inserire un servizio dal Razor contenitore del servizio in una visualizzazione. Per altre informazioni, vedere Inserimento di dipendenze in visualizzazioni.

@layout

Questo scenario si applica solo Razor ai componenti ( .razor ).

La @layout direttiva specifica un layout per i componenti Razor instradabili con una @page direttiva . I componenti di layout vengono usati per evitare la duplicazione e l'incoerenza del codice. Per altre informazioni, vedere BlazorASP.NET Core Layout.

@model

Questo scenario si applica solo alle visualizzazioni MVC Razor e alle pagine ( .cshtml ).

La direttiva @model specifica il tipo del modello passato a una vista o a una pagina:

@model TypeNameOfModel

In un ASP.NET Core app MVC o Pages creata Razor con singoli account utente, contiene la dichiarazione Views/Account/Login.cshtml del modello seguente:

@model LoginViewModel

La classe generata eredita da RazorPage<dynamic>:

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Razor espone una Model proprietà per l'accesso al modello passato alla vista:

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

La direttiva @model specifica il tipo della proprietà Model. La direttiva specifica l'elemento T in RazorPage<T> che ha generato la classe da cui deriva la visualizzazione. Se la direttiva @model non è specificata, la proprietà Model è di tipo dynamic. Per altre informazioni, vedere Modelli fortemente tipizzato e la @model parola chiave.

@namespace

La direttiva @namespace:

  • Imposta lo spazio dei nomi della classe della pagina, della Razor visualizzazione MVC o del Razor componente generato.
  • Imposta gli spazi dei nomi derivati dalla radice di pagine, viste o classi di componenti dal file imports più vicino nell'albero di directory, _ViewImports.cshtml (viste o pagine) o _Imports.razor Razor (componenti).
@namespace Your.Namespace.Here

Per Razor l'esempio Pages illustrato nella tabella seguente:

  • Ogni pagina importa Pages/_ViewImports.cshtml .
  • Pages/_ViewImports.cshtml contiene @namespace Hello.World .
  • Ogni pagina ha Hello.World come radice dello spazio dei nomi.
Pagina Spazio dei nomi
Pages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml Hello.World.MorePages.EvenMorePages

Le relazioni precedenti si applicano ai file di importazione usati con le viste e i componenti Razor MVC.

Quando più file di importazione hanno una direttiva @namespace, per impostare lo spazio dei nomi radice, viene usato il file più vicino alla pagina, alla vista o al componente nell'albero di directory.

Se la cartella nell'esempio precedente include un file imports con (o il file contiene ), il risultato viene EvenMorePages @namespace Another.Planet visualizzato nella tabella Pages/MorePages/EvenMorePages/Page.cshtml @namespace Another.Planet seguente.

Pagina Spazio dei nomi
Pages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml Another.Planet

@page

La direttiva @page ha effetti diversi a seconda del tipo del file in cui viene visualizzata. La direttiva:

@preservewhitespace

Questo scenario si applica solo Razor ai componenti ( .razor ).

Se impostato su (impostazione predefinita), lo spazio vuoto nel markup sottoposto false a rendering dai componenti ( ) viene rimosso Razor .razor se:

  • Iniziale o finale all'interno di un elemento.
  • Iniziale o finale all'interno di un RenderFragment parametro. Ad esempio, il contenuto figlio passato a un altro componente.
  • Precede o segue un blocco di codice C#, ad esempio @if o @foreach .

@section

Questo scenario si applica solo alle visualizzazioni MVC Razor e alle pagine ( .cshtml ).

La direttiva viene usata insieme ai layout MVC e Pages per consentire alle visualizzazioni o alle pagine di eseguire il rendering del contenuto @section in parti diverse della pagina HTML. Razor Per altre informazioni, vedere Layout in ASP.NET Core.

@using

La direttiva @using aggiunge la direttiva C# using alla visualizzazione generata:

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

Nei Razor componenti, @using controlla anche quali componenti sono nell'ambito.

Attributi delle direttive

Razor Gli attributi di direttiva sono rappresentati da espressioni implicite con parole chiave riservate che segue il @ simbolo . Un attributo di direttiva modifica in genere il modo in cui un elemento viene analizzato o abilita funzionalità diverse.

@attributes

Questo scenario si applica solo Razor ai componenti ( .razor ).

@attributes consente a un componente di eseguire il rendering di attributi non dichiarati. Per altre informazioni, vedere RazorASP.NET Core Componenti.

@bind

Questo scenario si applica solo Razor ai componenti ( .razor ).

Il data binding nei componenti viene eseguito con l'attributo @bind. Per altre informazioni, vedere BlazorASP.NET Core data binding.

@bind:culture

Questo scenario si applica solo Razor ai componenti ( .razor ).

Usare @bind:culture l'attributo con @bind l'attributo per fornire un oggetto System.Globalization.CultureInfo per l'analisi e la formattazione di un valore. Per altre informazioni, vedere BlazorASP.NET Core globalizzazione e localizzazione.

@on{EVENT}

Questo scenario si applica solo Razor ai componenti ( .razor ).

Razor fornisce funzionalità di gestione degli eventi per i componenti. Per altre informazioni, vedere BlazorASP.NET Core gestione degli eventi.

@on{EVENT}:preventDefault

Questo scenario si applica solo Razor ai componenti ( .razor ).

Impedisce l'azione predefinita per l'evento.

@on{EVENT}:stopPropagation

Questo scenario si applica solo Razor ai componenti ( .razor ).

Arresta la propagazione dell'evento.

@key

Questo scenario si applica solo Razor ai componenti ( .razor ).

L'attributo della direttiva @key fa in modo che l'algoritmo di controllo delle differenze tra componenti garantisca la conservazione degli elementi o dei componenti in base al valore della chiave. Per altre informazioni, vedere RazorASP.NET Core Componenti.

@ref

Questo scenario si applica solo Razor ai componenti ( .razor ).

I riferimenti ai componenti (@ref) consentono di fare riferimento a un'istanza di un componente in modo che sia possibile eseguire comandi su tale istanza. Per altre informazioni, vedere RazorASP.NET Core Componenti.

@typeparam

Questo scenario si applica solo Razor ai componenti ( .razor ).

La @typeparam direttiva dichiara un parametro di tipo generico per la classe del componente generata:

@typeparam TEntity

I tipi generici where con vincoli di tipo sono supportati:

@typeparam TEntity where TEntity : IEntity

Per altre informazioni, vedere gli articoli seguenti:

@typeparam

Questo scenario si applica solo Razor ai componenti ( .razor ).

La @typeparam direttiva dichiara un parametro di tipo generico per la classe del componente generata:

@typeparam TEntity

Per altre informazioni, vedere gli articoli seguenti:

Delegati Razor modello

Razor I modelli consentono di definire un frammento di interfaccia utente con il formato seguente:

@<tag>...</tag>

Nell'esempio seguente viene illustrato come specificare un delegato modello Razor come Func<T,TResult> . Per il parametro del metodo incapsulato dal delegato viene specificato il tipo dinamico. Come valore restituito del delegato viene specificato un tipo di oggetto. Il modello viene usato con un oggetto List<T> di Pet dotato della proprietà 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" }
    };
}

Il rendering del modello viene eseguito con pets in un'istruzione foreach:

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

Output sottoposto a rendering:

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

È anche possibile fornire un modello inline Razor come argomento di un metodo. Nell'esempio seguente il Repeat metodo riceve un Razor modello. Il metodo usa il modello per generare contenuto HTML tramite ripetizioni di elementi (item) ricavati da un elenco:

@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 l'elenco di animali domestici (pets) dell'esempio precedente, il metodo Repeat viene chiamato con:

  • List<T> di Pet.
  • Numero di ripetizioni di ogni animale domestico.
  • Modello inline da usare per gli elementi elenco di un elenco non ordinato.
<ul>
    @Repeat(pets, 3, @<li>@item.Name</li>)
</ul>

Output sottoposto a rendering:

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

Helper tag

Questo scenario si applica solo alle visualizzazioni MVC Razor e alle pagine ( .cshtml ).

Esistono tre direttive che riguardano gli helper tag.

Direttiva Funzione
@addTagHelper Rende gli helper tag disponibili per una visualizzazione.
@removeTagHelper Rimuove gli helper tag aggiunti in precedenza da una visualizzazione.
@tagHelperPrefix Specifica un prefisso del tag per abilitare il supporto dell'helper tag e renderne esplicito l'uso.

Razor parole chiave riservate

Razor Parole chiavi

  • page(Richiede ASP.NET Core 2.1 o versione successiva)
  • namespace
  • functions
  • inherits
  • model
  • section
  • helper(Non attualmente supportato da ASP.NET Core)

Razor Le parole chiave vengono precedute @(Razor Keyword) da un carattere di escape (ad esempio, @(functions) ).

Parole chiave Razor C#

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

Le parole chiave C# devono essere precedute da un doppio carattere Razor @(@C# Razor Keyword) di escape (ad esempio, @(@case) ). Il primo @ escape del Razor parser. Il secondo @ è il carattere di escape del parser C#.

Parole chiave riservate non usate da Razor

  • class

Esaminare la Razor classe C# generata per una vista

Razor L'SDK gestisce la compilazione dei Razor file. Quando si compila un progetto, Razor l'SDK genera obj/<build_configuration>/<target_framework_moniker>/Razor una directory nella radice del progetto. La struttura di Razor directory all'interno della directory rispecchia la struttura di directory del progetto.

Si consideri la struttura di directory seguente in un progetto Razor ASP.NET Core Pages:

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

La compilazione del progetto nella configurazione di debug genera la obj directory seguente:

 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

Per visualizzare la classe generata per Pages/Index.cshtml , aprire obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs .

Visualizzazione di ricerche e distinzione tra maiuscole e minuscole

Il Razor motore di visualizzazione esegue ricerche con distinzione tra maiuscole e minuscole per le viste. La ricerca effettiva è tuttavia determinata dal file system sottostante:

  • Origine basata su file:
    • Nei sistemi operativi con file system che non fanno distinzione tra maiuscole e minuscole (ad esempio, Windows), le ricerche del provider di file fisici non eseguono la distinzione tra maiuscole e minuscole. Ad esempio, return View("Test") genera corrispondenze per /Views/Home/Test.cshtml , e qualsiasi altra variante di maiuscole e /Views/home/test.cshtml minuscole.
    • Nei file system che fanno distinzione tra maiuscole e minuscole (ad esempio Linux, OS x e con EmbeddedFileProvider), le ricerche eseguono la distinzione tra maiuscole e minuscole. Ad esempio, corrisponde return View("Test") in modo specifico a /Views/Home/Test.cshtml .
  • Visualizzazioni precompilate: con ASP.NET Core 2.0 e versioni successive, la ricerca di visualizzazioni precompilate non esegue la distinzione tra maiuscole e minuscole in tutti i sistemi operativi. Questo comportamento è identico al comportamento del provider di file fisici in Windows. Se due visualizzazioni precompilate differiscono solo nelle lettere maiuscole e minuscole, il risultato di ricerca è non deterministico.

Gli sviluppatori sono invitati a far corrispondere le maiuscole e minuscole dei nomi di file e directory per quanto riguarda le maiuscole e minuscole di:

  • Nomi di area, controller e azione.
  • Razor Pagine.

La distinzione tra maiuscole e minuscole assicura che le distribuzioni trovino le proprie visualizzazioni indipendentemente dal file system sottostante.

Importazioni usate da Razor

Le importazioni seguenti vengono generate dai modelli Web ASP.NET Core per supportare Razor i file:

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;

Risorse aggiuntive

Introduzione alla ASP.NET Web con Razor La sintassi fornisce molti esempi di programmazione con Razor sintassi.