Razor-Syntaxreferenz für ASP.NET Core

Von Rick Anderson, Taylor Mullen und Dan Vicarel

Razor ist eine Markupsyntax zum Einbetten von .NET-basiertem Code in Webseiten. Die Razor-Syntax besteht aus dem Razor-Markup, C# und HTML. Dateien, die Razor enthalten, besitzen in der Regel die Dateierweiterung .cshtml. Razor befindet sich auch in Razor-Komponentendateien (.razor). Die Razor-Syntax ähnelt den Vorlagen-Engines verschiedener JavaScript-Frameworks für Single-Page-Webanwendungen (SPA), z. B. Angular, React, VueJs und Svelte. Weitere Informationen finden Sie unter Die in diesem Artikel beschriebenen Funktionen sind ab ASP.NET Core 3.0 veraltet.

Einführung in ASP.NET-Webprogrammierung mit der Razor-Syntax bietet viele Beispiele für die Programmierung mit der Razor-Syntax. Obwohl das Thema für ASP.NET und nicht für ASP.NET Core geschrieben wurde, gelten die meisten Beispiele auch für ASP.NET Core.

Rendern von HTML

Die Razor-Standardsprache ist C#. Das Rendern von HTML-Code aus Razor-Markup funktioniert genauso wie das Rendern von HTML aus einer HTML-Datei. Das HTML-Markup in .cshtmlRazor-Dateien wird unverändert vom Server gerendert.

Syntax von Razor

Razor unterstützt C# und verwendet für den Übergang von HTML zu C# das @-Symbol. Razor wertet C#-Ausdrücke aus und rendert sie in der HTML-Ausgabe.

Folgt auf ein @-Symbol ein für Razor reserviertes Schlüsselwort, wechselt es in ein Razor-spezifisches Markup. Andernfalls erfolgt der Übergang in normales HTML.

Verwenden Sie ein zweites @-Symbol, um im Razor-Markup ein @-Symbol mit Escapezeichen zu versehen:

<p>@@Username</p>

Der Code wird in HTML mit einem einzelnen @-Symbol gerendert:

<p>@Username</p>

Bei HTML-Attributen und Inhalt mit E-Mail-Adressen wird das @-Symbol nicht als ein Übergangszeichen behandelt. Die E-Mail-Adressen im folgenden Beispiel bleiben bei der Razor-Analyse unverändert:

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

Skalierbare Vektorgrafiken (SVG)

foreignObject-Elemente von SVG werden unterstützt:

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

Implizite Razor-Ausdrücke

Implizite Razor-Ausdrücke beginnen mit @, gefolgt von C#-Code:

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

Mit Ausnahme des C#-Schlüsselworts await dürfen implizite Ausdrücke keine Leerzeichen enthalten. Wird die C#-Anweisung eindeutig beendet, können auch Leerzeichen verwendet werden:

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

Implizite Ausdrücke dürfen keine C#-Generics enthalten, da die Zeichen innerhalb der Klammern (<>) als HTML-Tag interpretiert werden. Der folgende Code ist ungültig:

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

Der vorhergehende Code erzeugt einen Compilerfehler, der folgendermaßen aussehen kann:

  • Das Element „int“ wurde nicht geschlossen. Alle Elemente müssen entweder selbstschließend sein oder ein zugehöriges Endtag besitzen.
  • Die Methodengruppe „GenericMethod“ kann nicht in den Nichtdelegattyp „Objekt“ konvertiert werden. Wollten Sie die Methode aufrufen?

Generische Methodenaufrufe müssen von einem expliziten Razor-Ausdruck oder einem Razor-Codeblock umschlossen werden.

Explizite Razor-Ausdrücke

Explizite Razor-Ausdrücke bestehen aus einem @-Symbol mit ausgeglichenen Klammern. Zum Rendern der Uhrzeit von letzter Woche wird folgendes Razor-Markup verwendet:

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

Jeglicher Inhalt innerhalb der @()-Klammer wird ausgewertet und in der Ausgabe gerendert.

Die im vorherigen Abschnitt beschriebenen impliziten Ausdrücke dürfen grundsätzlich keine Leerzeichen enthalten. Im folgenden Code wird eine Woche nicht von der aktuellen Uhrzeit abgezogen:

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

Der Code rendert den folgenden HTML-Code:

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

Explizite Ausdrücke können zum Verketten von Text mit einem Ergebnis des Ausdrucks verwendet werden:

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

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

Ohne den expliziten Ausdruck wird <p>Age@joe.Age</p> als E-Mail-Adresse behandelt und <p>Age@joe.Age</p> gerendert. <p>Age33</p> wird gerendert, wenn es als expliziter Ausdruck geschrieben wird.

Explizite Ausdrücke können zum Rendern der Ausgabe von generischen Methoden in .cshtml-Dateien verwendet werden. Das folgende Markup zeigt, wie der weiter oben gezeigte Fehler behoben wird, der durch die Klammern einer generischen C#-Funktion verursacht wurde. Der Code wird als expliziter Ausdruck geschrieben:

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

Codieren von Ausdrücken

C#-Ausdrücke, die als Zeichenfolge ausgewertet werden, werden HTML-codiert. C#-Ausdrücke, die als IHtmlContent ausgewertet werden, werden direkt durch IHtmlContent.WriteTo gerendert. C#-Ausdrücke, die nicht als IHtmlContent ausgewertet werden, werden durch ToString in eine Zeichenfolge konvertiert und vor dem Rendern codiert.

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

Der oben gezeigte Code generiert den folgenden HTML-Code:

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

Der HTML-Code wird im Browser als Nur-Text angezeigt:

<span>Hello World</span>

Die Ausgabe HtmlHelper.Raw wird nicht codiert, sondern als HTML-Markup gerendert.

Warnung

Die Verwendung von HtmlHelper.Raw bei einer nicht bereinigten Benutzereingabe stellt ein Sicherheitsrisiko dar. Benutzereingaben können schädlichen JavaScript-Code oder andere Sicherheitsrisiken enthalten. Das Bereinigen von Benutzereingaben ist schwierig. Vermeiden Sie daher die Verwendung von HtmlHelper.Raw bei Benutzereingaben.

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

Der Code rendert den folgenden HTML-Code:

<span>Hello World</span>

Razor-Codeblöcke

Razor-Codeblöcke beginnen mit @ und sind in {} eingeschlossen. Im Gegensatz zu Ausdrücken wird C#-Code in Codeblöcken nicht gerendert. Codeblöcke und Ausdrücke in einer Ansicht nutzen den gleichen Bereich und werden der Reihe nach definiert:

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

Der Code rendert den folgenden HTML-Code:

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

Deklarieren Sie in Codeblöcken lokale Funktionen mit Markup als Vorlagenmethoden:

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

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

Der Code rendert den folgenden HTML-Code:

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

Implizite Übergänge

Die Standardsprache in einem Codeblock ist C#. Die Razor Page kann jedoch zurück zu HTML wechseln:

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

Durch Trennzeichen getrennte explizite Übergänge

Soll ein Unterabschnitt eines Codeblocks in HTML gerendert werden, umschließen Sie die Zeichen, die gerendert werden sollen, mit dem Razor-Tag <text>:

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

Verwenden Sie diese Methode zum Rendern von HTML-Code, der nicht von einem HTML-Tag umschlossen ist. Ohne HTML- oder Razor-Tag tritt ein Razor-Laufzeitfehler auf.

Das <text>-Tag ist nützlich, wenn Sie beim Rendern von Inhalt Leerzeichen steuern möchten:

  • Nur der Inhalt zwischen den <text>-Tags wird gerendert.
  • In der HTML-Ausgabe werden keine Leerzeichen vor oder nach dem <text>-Tag angezeigt.

Explizite Zeilenübergänge

Verwenden Sie die @:-Syntax, um den Rest einer kompletten Zeile als HTML-Code in einem Codeblock zu rendern:

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

Ohne das @:-Symbol im Code wird ein Razor-Laufzeitfehler erzeugt.

Zusätzliche @-Zeichen in einer Razor-Datei können zu Compilerfehlern bei späteren Anweisungen im Block führen. Diese zusätzlichen @-Compilerfehler:

  • Können schwer nachvollziehbar sein, da der tatsächliche Fehler vor dem gemeldeten Fehler auftritt.
  • Treten häufig auf, wenn mehrere implizite/explizite Ausdrücke in einem einzigen Codeblock kombiniert werden.

Rendern von bedingten Attributen

Razor lässt Attribute, die nicht benötigt werden, automatisch aus. Wenn der übergebene Wert null oder false ist, wird das Attribut nicht gerendert.

Berücksichtigen Sie beispielsweise Folgendes 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" />

Das oben gezeigte Razor-Markup generiert den folgenden HTML-Code:

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

Steuerungsstrukturen

Steuerungsstrukturen sind eine Erweiterung von Codeblöcken. Alle Aspekte von Codeblöcken (Übergang zu Markup, Inline-C#) gelten auch für die folgenden Strukturen:

Bedingungen @if, else if, else, and @switch

@if steuert, wann der Code ausgeführt wird:

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

else und else if erfordern kein @-Symbol:

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

Im folgenden Markup wird die Verwendung einer switch-Anweisung veranschaulicht:

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

Durchlaufen von @for, @foreach, @while, and @do while

Auf Vorlagen basierender HTML-Code kann mit Anweisungen zur Steuerung von Schleifen gerendert werden. So rendern Sie eine Liste mit Personen.

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

Die folgenden Schleifenanweisungen werden unterstützt:

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

Zusammengesetztes @using

In C# kann mit einer using-Anweisung sichergestellt werden, dass ein Objekt freigegeben wurde. In Razor wird derselbe Mechanismus verwendet, um HTML-Hilfsprogramme zu erstellen, die zusätzliche Inhalte enthalten. Im folgenden Code wird ein <form>-Tag mit der @using-Anweisung durch HTML-Hilfsprogramme gerendert:

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

@try, catch, finally

Die Behandlung von Ausnahmen ist vergleichbar mit 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 kann kritische Abschnitte mit lock-Anweisungen schützen:

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

Kommentare

Razor unterstützt C#- und HTML-Kommentare:

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

Der Code rendert den folgenden HTML-Code:

<!-- HTML comment -->

Razor-Kommentare werden vom Server entfernt, bevor die Webseite gerendert wird. Zur Abgrenzung der Kommentare verwendet Razor@* *@. Der folgende Code ist auskommentiert, damit vom Server kein Markup gerendert wird:

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

Anweisungen

Razor-Anweisungen werden durch implizite Ausdrücke mit reservierten Schlüsselwörtern nach dem @-Symbol dargestellt. Eine Anweisung ändert in der Regel die Art und Weise, wie eine Ansicht kompiliert wird oder funktioniert.

Wenn Sie wissen, wie von Razor Code für eine Ansicht generiert wird, erleichtert dies das Verständnis dafür, wie Anweisungen funktionieren.

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

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

Durch den Code wird eine Klasse ähnlich der folgenden Klasse generiert:

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

Im Abschnitt Überprüfen der Razor-C#-Klasse, die für eine Ansicht generiert wurde weiter unten wird erklärt, wie die generierte Klasse angezeigt wird.

@attribute

Die @attribute-Anweisung fügt das angegebene Attribut zu der Klasse der generierten Seite oder Ansicht hinzu. Im folgenden Beispiel wird das [Authorize]-Attribut hinzugefügt:

@attribute [Authorize]

Die @attribute-Direktive kann auch verwendet werden, um eine konstantenbasierte Routenvorlage in einer Razor-Komponente anzugeben. Im folgenden Beispiel wird die Anweisung @page in einer Komponente durch die Anweisung @attribute und die konstantenbasierte Routenvorlage in Constants.CounterRoute ersetzt, die an anderer Stelle in der App auf /counter festgelegt wird:

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

@code

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Der @code-Block ermöglicht einer Razor-Komponente das Hinzufügen von C#-Membern (Feldern, Eigenschaften und Methoden) zu einer Komponente:

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

Für Razor-Komponenten ist @code ein Alias von @functions und wird über @functions empfohlen. Mehrere @code-Blöcke sind zulässig.

@functions

Die @functions-Anweisung ermöglicht das Hinzufügen von C#-Membern (Feldern, Eigenschaften und Methoden) zur generierten Klasse:

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

Verwenden Sie in Razor-Komponenten@code über @functions, um C#-Member hinzuzufügen.

Beispiel:

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

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

Der Code generiert das folgende HTML-Markup:

<div>From method: Hello</div>

Der folgende Code wird in der Razor-C#-Klasse generiert:

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

@functions-Methoden dienen als Vorlagenmethoden, wenn sie Markup aufweisen:

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

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

Der Code rendert den folgenden HTML-Code:

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

@implements

Die @implements-Anweisung implementiert eine Schnittstelle für die generierte Klasse.

Im folgenden Beispiel wird System.IDisposable implementiert, sodass die Dispose-Methode aufgerufen werden kann:

@implements IDisposable

<h1>Example</h1>

@functions {
    private bool _isDisposed;

    ...

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

@inherits

Die @inherits-Anweisung bietet uneingeschränkten Zugriff auf die Klasse, die die Ansicht erbt:

@inherits TypeNameOfClassToInheritFrom

Der folgende Code ist ein benutzerdefinierter Typ von Razor Page:

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 wird in einer Ansicht angezeigt:

@inherits CustomRazorPage<TModel>

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

Der Code rendert den folgenden HTML-Code:

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

@model und @inherits können in derselben Ansicht verwendet werden. @inherits kann sich in einer Datei _ViewImports.cshtml befinden, die die Ansicht importiert:

@inherits CustomRazorPage<TModel>

Der folgende Code ist ein Beispiel für eine stark typisierte Ansicht:

@inherits CustomRazorPage<TModel>

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

Wird „rick@contoso.com“ im Modell übergeben, generiert die Ansicht das folgende HTML-Markup:

<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

Mit der @inject-Anweisung kann die Razor Page einen Dienst aus dem Dienstcontainer in eine Ansicht einfügen. Weitere Informationen finden Sie unter Dependency Injection in Ansichten.

@layout

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Die @layout-Direktive gibt ein Layout für routingfähige Razor-Komponenten an, die über eine @page-Anweisung verfügen. Layoutkomponenten werden verwendet, um Codeduplizierung und Inkonsistenzen zu vermeiden. Weitere Informationen finden Sie unter ASP.NET Core Blazor-Layouts.

@model

Dieses Szenario gilt nur für MVC-Ansichten und Razor Pages (.cshtml).

Die @model-Anweisung gibt den Typ des Modells an, das an eine Ansicht oder Seite übergeben wird:

@model TypeNameOfModel

In einer mit einzelnen Benutzerkonten erstellten ASP.NET Core MVC- oder Razor Pages-App enthält Views/Account/Login.cshtml die folgende Modelldeklaration:

@model LoginViewModel

Die generierte Klasse erbt von RazorPage<LoginViewModel>:

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Razor macht eine Model-Eigenschaft für den Zugriff auf das an die Ansicht übergebene Modell verfügbar:

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

Die @model-Anweisung gibt den Typ der Model-Eigenschaft an. Die Anweisung gibt das T in RazorPage<T> der generierten Klasse an, von der die Ansicht abgeleitet wird. Wird die @model-Anweisung nicht angegeben, hat die Model-Eigenschaft den Typ dynamic. Weitere Informationen finden Sie unter Strongly typed models and the @model keyword.

@namespace

Die @namespace-Anweisung:

  • Legt den Namespace der Klasse der generierten Razor Page, der MVC-Ansicht oder der Razor-Komponente fest.
  • Legt die vom Stamm abgeleiteten Namespaces einer Seiten-, Ansichts- oder Komponentenklasse aus der nächsten Importdatei in der Verzeichnisstruktur fest: _ViewImports.cshtml(Ansichten oder Seiten) oder _Imports.razor (Razor-Komponenten).
@namespace Your.Namespace.Here

Für das Razor Pages-Beispiel in der folgenden Tabelle gilt:

  • Jede Seite importiert Pages/_ViewImports.cshtml.
  • Pages/_ViewImports.cshtml enthält @namespace Hello.World.
  • Jede Seite weist Hello.World als Stamm ihres Namespace auf.
Seite Namespace
Pages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml Hello.World.MorePages.EvenMorePages

Die oben genannten Beziehungen gelten für Importdateien, die mit MVC-Ansichten und Razor-Komponenten verwendet werden.

Wenn mehrere Importdateien über eine @namespace-Anweisung verfügen, wird die Datei verwendet, die der Seite, der Ansicht oder der Komponente in der Verzeichnisstruktur am nächsten ist, um den Stammnamespace festzulegen.

Wenn der Ordner EvenMorePages im Beispiel oben eine Importdatei mit @namespace Another.Planet enthält (oder die Datei Pages/MorePages/EvenMorePages/Page.cshtml@namespace Another.Planet enthält), finden Sie das Ergebnis in der folgenden Tabelle.

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

@page

Die @page-Anweisung hat abhängig vom Typ der Datei, in der Sie verwendet wird, unterschiedliche Auswirkungen. Für die Anweisung gilt:

@preservewhitespace

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Bei Festlegung auf false (Standardeinstellung) werden Leerzeichen im gerenderten Markup aus Razor-Komponenten (.razor) entfernt, wenn:

  • Sie stehen in einem Element am Anfang oder am Ende.
  • Sie stehen in einem RenderFragment-Parameter am Anfang oder am Ende. Ein Beispiel hierfür ist untergeordneter Inhalt, der an eine andere Komponente übergeben wird
  • Sie stehen am Anfang oder Ende eines C#-Codeblocks wie @if oder @foreach.

@rendermode

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Legt den Rendermodus einer Razor-Komponente fest:

  • InteractiveServer: Wendet das interaktive Serverrendering mit Blazor Server an.
  • InteractiveWebAssembly: Wendet das interaktive WebAssembly-Rendering mithilfe von Blazor WebAssembly an
  • InteractiveAuto: Wendet zunächst das interaktive WebAssembly-Rendering mithilfe von Blazor Server und dann das interaktive WebAssembly-Rendering mithilfe von WebAssembly bei nachfolgenden Besuche an, nachdem das Blazor-Bundle heruntergeladen wurde

Für eine Komponenteninstanz:

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

In der Komponentendefinition:

@rendermode InteractiveServer

Hinweis

BlazorVorlagen enthalten eine statische using Direktive für RenderMode die Datei (_Imports) der App Components/_Imports.razor für kürzere @rendermode Syntax:

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

Ohne die vorangehende Direktive müssen Komponenten die statische RenderMode Klasse in @rendermode der Syntax explizit angeben:

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

Weitere Informationen, einschließlich Anleitungen zum Deaktivieren des Prärenderings mit dem Direktive/Direktive-Attribut, finden Sie unter ASP.NET Core-RendermodiBlazor.

@section

Dieses Szenario gilt nur für MVC-Ansichten und Razor Pages (.cshtml).

Die @section-Anweisung wird in Verbindung mit MVC- und Razor Pages-Layouts verwendet, damit Ansichten Seiten Inhalte in verschiedenen Teilen der HTML-Seite rendern können. Weitere Informationen finden Sie unter Layout in ASP.NET Core.

@typeparam

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Die @typeparam-Direktive deklariert einen generischen Typparameter für die generierte Komponentenklasse:

@typeparam TEntity

Folgende generische Typen mit den Typeinschränkungen where werden unterstützt:

@typeparam TEntity where TEntity : IEntity

Weitere Informationen finden Sie in den folgenden Artikeln:

@using

Die @using-Anweisung fügt die using-C#-Anweisung der generierten Ansicht hinzu:

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

@using steuert in Razor-Komponenten außerdem, welche Komponenten sich im Gültigkeitsbereich befinden.

Direktivenattribute

Attribute von Razor-Anweisungen werden durch implizite Ausdrücke mit reservierten Schlüsselwörtern nach dem @-Symbol dargestellt. Ein Anweisungsattribut ändert in der Regel die Art und Weise, wie ein Element kompiliert wird oder funktioniert.

@attributes

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

@attributes ermöglicht es einer Komponente, nicht deklarierte Attribute zu rendern. Weitere Informationen finden Sie unter ASP.NET Core Blazor-Attributsplatting und beliebige Parameter.

@bind

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Die Datenbindung in-Komponenten wird mit dem @bind-Attribut erreicht. Weitere Informationen finden Sie unter Blazor-Datenbindung in ASP.NET Core.

@bind:culture

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Verwenden Sie das @bind:culture-Attribut mit dem @bind-Attribut, um eine System.Globalization.CultureInfo zum Analysieren und Formatieren eines Werts bereitzustellen. Weitere Informationen finden Sie unter Blazor in ASP.NET Core: Globalisierung und Lokalisierung.

@formname

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

@formname weist dem einfachen HTML-Formular einer Razor-Komponente oder einem auf EditForm basierenden Formular (Editform-Dokumentation) einen Formularnamen zu. Der Wert von @formname sollte eindeutig sein, um Formkonflikte in den folgenden Situationen zu verhindern:

  • Ein Formular wird in einer Komponente mit mehreren Formularen eingefügt.
  • Ein Formular stammt aus einer externen Klassenbibliothek, in der Regel ein NuGet-Paket, für eine Komponente mit mehreren Formularen, und der App-Ersteller steuert nicht den Quellcode der Bibliothek, um einen anderen externen Formularnamen als einen Namen festzulegen, der von einem anderen Formular in der Komponente verwendet wird.

Weitere Informationen und Beispiele finden Sie unter Übersicht über ASP.NET Core Blazor-Formulare.

@on{EVENT}

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Razor stellt Ereignisbehandlungsfunktionen für Komponenten bereit. Weitere Informationen finden Sie unter Ereignisbehandlung in Blazor in ASP.NET Core.

@on{EVENT}:preventDefault

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Verhindert die Standardaktion für das Ereignis.

@on{EVENT}:stopPropagation

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Beendet die Ereignisweitergabe für das Ereignis.

@key

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Das Direktivenattribut @key bewirkt, dass der Komponentenvergleichsalgorithmus die Erhaltung von Elementen oder Komponenten basierend auf dem Wert des Schlüssels garantiert. Weitere Informationen finden Sie unter Beibehalten von Element-, Komponenten- und Modellbeziehungen in ASP.NET Core Blazor.

@ref

Dieses Szenario gilt nur für Razor-Komponenten (.razor).

Komponentenverweise (@ref) bieten eine Möglichkeit, auf eine Komponenteninstanz zu verweisen, damit Sie Befehle für diese Instanz ausgeben können. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

Vorlagenbasierte Razor-Delegate

Dieses Szenario gilt nur für MVC-Ansichten und Razor Pages (.cshtml).

Mit Razor-Vorlagen können Sie einen Ausschnitt der Benutzeroberfläche mit dem folgenden Format festlegen:

@<tag>...</tag>

Im folgenden Beispiel wird veranschaulicht, wie ein auf Vorlagen basierender Razor-Delegat als Func<T,TResult> angegeben wird. Der Typ dynamic wird für den Parameter der Methode angegeben, die der Delegat einkapselt. Ein object-Typ wird als Rückgabewert des Delegats angegeben. Die Vorlage wird mit List<T> von Pet mit einer Name-Eigenschaft verwendet.

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

Die Vorlage wird mit pets in einer foreach-Anweisung gerendert:

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

Gerenderte Ausgabe:

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

Sie können auch eine Razor-Inlinevorlage als Argument für eine Methode angeben. Im folgenden Beispiel nimmt die Repeat-Methode eine Razor-Vorlage an. Die Methode verwendet die Vorlage dann zum Erstellen von HTML-Inhalten mit Wiederholungen von Elementen aus einer Liste:

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

Wird die Liste mit Haustieren aus dem vorherigen Beispiel verwendet, wird die Repeat-Methode wie folgt aufgerufen:

  • List<T> von Pet
  • Anzahl der Wiederholungen für jedes Haustier
  • Inlinevorlage zur Verwendung für die Elemente einer unsortierten Liste
<ul>
    @Repeat(pets, 3, @<li>@item.Name</li>)
</ul>

Gerenderte Ausgabe:

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

Taghilfsprogramme

Dieses Szenario gilt nur für MVC-Ansichten und Razor Pages (.cshtml).

Die folgenden drei Anweisungen gehören zu den Taghilfsprogrammen.

Anweisung Funktion
@addTagHelper Macht Taghilfsprogramme für eine Ansicht verfügbar.
@removeTagHelper Entfernt die zuvor aus einer Ansicht hinzugefügten Taghilfsprogramme.
@tagHelperPrefix Gibt ein Tagpräfix an, um Unterstützung für Taghilfsprogramme zu aktivieren und ihre Verwendung explizit festzulegen.

Reservierte Razor-Schlüsselwörter

Razor-Schlüsselwörter

  • page
  • namespace
  • functions
  • inherits
  • model
  • section
  • helper (wird derzeit nicht von ASP.NET Core unterstützt)

Razor-Schlüsselwörter werden mit dem Escapezeichen @(Razor Keyword) versehen (z. B. @(functions)).

Razor-C#-Schlüsselwörter

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

Razor-C#-Schlüsselwörter werden mit einem doppeltem Escapezeichen @(@C# Razor Keyword) versehen (z. B. @(@case)). Das erste @ dient als Escapezeichen für den Razor-Parser. Das zweite @ dient als Escapezeichen für den C#-Parser.

Reservierte Schlüsselwörter, die nicht von Razor verwendet werden

  • class

Überprüfen der Razor-C#-Klasse, die für eine Ansicht generiert wurde

Das Razor SDK übernimmt die Kompilierung von Razor-Dateien. Standardmäßig werden die generierten Codedateien nicht ausgegeben. Um das Ausgeben von Codedateien zu aktivieren, legen Sie die EmitCompilerGeneratedFiles-Anweisung in der Projektdatei (.csproj) auf true fest:

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

Beim Erstellen eines 6.0-Projekts (net6.0) in der Debug-Buildkonfiguration generiert das Razor SDK ein Verzeichnis obj/Debug/net6.0/generated/ im Projektstamm. Das Unterverzeichnis enthält die ausgegebenen Razor Pages-Codedateien.

Das Razor SDK übernimmt die Kompilierung von Razor-Dateien. Beim Erstellen eines Projekts generiert das Razor SDK ein Verzeichnis obj/{BUILD CONFIGURATION}/{TARGET FRAMEWORK MONIKER}/Razor im Stammverzeichnis des Projekts. Die Verzeichnisstruktur im Razor-Verzeichnis spiegelt die Verzeichnisstruktur des Projekts.

Beachten Sie die folgende Verzeichnisstruktur in einem Razor Pages-Projekt in ASP.NET Core 2.1:

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

Wenn Sie das Projekt mit der Debug-Konfiguration zum Debuggen erstellen, wird folgendes obj-Verzeichnis erstellt:

 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

Öffnen Sie obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs, um die generierte Klasse für Pages/Index.cshtml anzuzeigen.

Ansicht der Suchvorgänge und Groß-/Kleinschreibung

Die Razor-Ansichts-Engine führt für Ansichten Suchvorgänge aus, die Groß-/Kleinschreibung berücksichtigen. Der tatsächliche Suchvorgang wird jedoch vom zugrunde liegenden Dateisystem bestimmt:

  • Dateibasierte Quelle:
    • Bei Betriebssystemen, die Dateisysteme ohne Berücksichtigung von Groß-/Kleinschreibung verwenden (z.B. Windows), wird bei Suchvorgängen nach physischen Dateianbietern die Groß- und Kleinschreibung nicht berücksichtigt. Beispielsweise ergibt return View("Test") Übereinstimmungen für /Views/Home/Test.cshtml, /Views/home/test.cshtml und jede andere Variante von Groß-/Kleinschreibung.
    • Bei Dateisystemen, die die Groß-/Kleinschreibung berücksichtigen (z.B. Linux, OSX sowie mit EmbeddedFileProvider), wird die Groß-/Kleinschreibung auch bei Suchvorgängen berücksichtigt. Beispielsweise stimmt return View("Test") genau mit /Views/Home/Test.cshtml überein.
  • Vorkompilierte Ansichten: Ab ASP.NET Core 2.0 wird bei der Suche nach vorkompilierten Ansichten unter allen Betriebssystemen die Groß-/Kleinschreibung nicht berücksichtigt. Das Verhalten ist mit dem des physischen Dateianbieters unter Windows identisch. Unterscheiden sich zwei vorkompilierte Ansichten nur in der Groß-/Kleinschreibung, ist das Ergebnis der Suche nicht deterministisch.

Entwicklern wird empfohlen, sich bei der Groß-/Kleinschreibung von Datei- und Verzeichnisnamen an der Schreibweise folgender Begriffe zu orientieren:

  • Bereichs-, Controller- und Aktionsnamen
  • Razor Pages.

Durch Überprüfung der Groß-/Kleinschreibung wird sichergestellt, dass die entsprechenden Ansichten für die Bereitstellungen unabhängig von dem zugrunde liegenden Dateisystem gefunden werden.

Importe, die von Razorverwendet werden.

Die folgenden Importe werden von den ASP.NET Core Webvorlagen generiert, um Razor-Dateien zu unterstützen:

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;

Zusätzliche Ressourcen

Einführung in ASP.NET-Webprogrammierung mit der Razor-Syntax bietet viele Beispiele für die Programmierung mit der Razor-Syntax.