Справочник по синтаксису Razor для ASP.NET CoreRazor syntax reference for ASP.NET Core

По Рик Андерсон (, Кузнецова Маллени " викарел "By Rick Anderson, Taylor Mullen, and Dan Vicarel

Razor — это синтаксис разметки для внедрения в веб-страницы серверного кода.Razor is a markup syntax for embedding server-based code into webpages. Синтаксис Razor состоит из разметки Razor, C# и HTML.The Razor syntax consists of Razor markup, C#, and HTML. Файлы, содержащие Razor, обычно имеют расширение CSHTML.Files containing Razor generally have a .cshtml file extension. Razor также находится в файлах компонентов Razor ( .razor).Razor is also found in Razor components files (.razor).

Отрисовка HTMLRendering HTML

Языком Razor по умолчанию является HTML.The default Razor language is HTML. Отрисовка HTML из разметки Razor ничем не отличается от отрисовки из HTML-файла.Rendering HTML from Razor markup is no different than rendering HTML from an HTML file. Сервер отображает разметку HTML в CSHTML-файлах Razor без изменений.HTML markup in .cshtml Razor files is rendered by the server unchanged.

Синтаксис RazorRazor syntax

Razor поддерживает C# и использует символ @ для перехода с HTML на C#.Razor supports C# and uses the @ symbol to transition from HTML to C#. Razor вычисляет выражения C# и отображает их в выходных данных HTML.Razor evaluates C# expressions and renders them in the HTML output.

Если за символом @ следует зарезервированное ключевое слово Razor, он переходит на разметку Razor.When an @ symbol is followed by a Razor reserved keyword, it transitions into Razor-specific markup. В противном случае он переходит на обычный C#.Otherwise, it transitions into plain C#.

В качестве escape-символа для @ в разметке Razor используйте второй символ @:To escape an @ symbol in Razor markup, use a second @ symbol:

<p>@@Username</p>

Код будет отображен в HTML с одним символом @:The code is rendered in HTML with a single @ symbol:

<p>@Username</p>

HTML-атрибуты и содержимое, включающие адреса электронной почты, не расценивают символ @ как символ перехода.HTML attributes and content containing email addresses don't treat the @ symbol as a transition character. В следующем примере синтаксический анализ Razor не затрагивает адреса электронной почты:The email addresses in the following example are untouched by Razor parsing:

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

Неявные выражения RazorImplicit Razor expressions

Неявные выражения Razor начинаются с символа @, за которым следует код C#:Implicit Razor expressions start with @ followed by C# code:

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

Неявные выражения не должны содержать пробелов. Исключением является ключевое слово C# await.With the exception of the C# await keyword, implicit expressions must not contain spaces. Если оператор C# имеет четкое окончание, пробелы вставлять можно:If the C# statement has a clear ending, spaces can be intermingled:

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

Неявные выражения не могут содержать универсальные шаблоны C#, так как символы в угловых скобках (<>) интерпретируются как тег HTML.Implicit expressions cannot contain C# generics, as the characters inside the brackets (<>) are interpreted as an HTML tag. Следующий код является недопустимым:The following code is not valid:

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

Приведенный выше код вызывает ошибку компилятора примерно следующего вида:The preceding code generates a compiler error similar to one of the following:

  • Элемент "int" не был закрыт.The "int" element wasn't closed. Все элементы должны быть самозакрывающимися или иметь соответствующий закрывающий тег.All elements must be either self-closing or have a matching end tag.
  • Не удается преобразовать группу методов "GenericMethod" в не являющийся делегатом тип "object".Cannot convert method group 'GenericMethod' to non-delegate type 'object'. Предполагалось вызывать этот метод?Did you intend to invoke the method?`

Вызовы универсальных методов должны быть заключены в явное выражение Razor или блок кода Razor.Generic method calls must be wrapped in an explicit Razor expression or a Razor code block.

Явные выражения RazorExplicit Razor expressions

Явные выражения Razor состоят из символа @ с соответствующими открывающими и закрывающими скобками.Explicit Razor expressions consist of an @ symbol with balanced parenthesis. Для отображения времени прошлой недели используется следующая разметка Razor:To render last week's time, the following Razor markup is used:

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

Любое содержимое в скобках @() вычисляется и отображается в выходных данных.Any content within the @() parenthesis is evaluated and rendered to the output.

Неявные выражения, описанные в предыдущем разделе, обычно не содержат пробелов.Implicit expressions, described in the previous section, generally can't contain spaces. В следующем коде из значения текущего времени неделя не вычитается:In the following code, one week isn't subtracted from the current time:

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

Код отображает следующий HTML:The code renders the following HTML:

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

Явные выражения позволяют объединять результат своего выполнения с дополнительным текстом:Explicit expressions can be used to concatenate text with an expression result:

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

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

Без явного выражения <p>Age@joe.Age</p> обрабатывается как адрес электронной почты, и на выходе отображается <p>Age@joe.Age</p>.Without the explicit expression, <p>Age@joe.Age</p> is treated as an email address, and <p>Age@joe.Age</p> is rendered. Если же текст написан как явное выражение, то вы получите <p>Age33</p>.When written as an explicit expression, <p>Age33</p> is rendered.

Вы можете использовать явные выражения для отображения выходных данных из универсальных методов в файлах CSHTML.Explicit expressions can be used to render output from generic methods in .cshtml files. В следующем примере показано, как исправить ошибку, показанную ранее и вызванную скобками в универсальном шаблоне C#.The following markup shows how to correct the error shown earlier caused by the brackets of a C# generic. Код записывается как явное выражение:The code is written as an explicit expression:

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

Кодирование выраженийExpression encoding

Выражения C#, которые имеют строковое выходное значение, кодируются в формате HTML.C# expressions that evaluate to a string are HTML encoded. Выражения C#, которые имеют значение IHtmlContent, обрабатываются непосредственно с помощью IHtmlContent.WriteTo.C# expressions that evaluate to IHtmlContent are rendered directly through IHtmlContent.WriteTo. Выражения C#, которые не имеют выходное значение IHtmlContent, преобразуются в строку с помощью ToString и кодируются перед обработкой.C# expressions that don't evaluate to IHtmlContent are converted to a string by ToString and encoded before they're rendered.

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

Код отображает следующий HTML:The code renders the following HTML:

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

HTML отображается в обозревателе следующим образом:The HTML is shown in the browser as:

<span>Hello World</span>

Выходные данные HtmlHelper.Raw не кодируются, но отображаются в виде разметки HTML.HtmlHelper.Raw output isn't encoded but rendered as HTML markup.

Предупреждение

Использование HtmlHelper.Raw с непроверенными входными данными пользователя представляет угрозу безопасности.Using HtmlHelper.Raw on unsanitized user input is a security risk. Эти входные данные могут содержать вредоносный код JavaScript или другие эксплойты.User input might contain malicious JavaScript or other exploits. Очистка вводимых пользователем данных является сложной задачей.Sanitizing user input is difficult. Старайтесь не использовать HtmlHelper.Raw с такими данными.Avoid using HtmlHelper.Raw with user input.

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

Код отображает следующий HTML:The code renders the following HTML:

<span>Hello World</span>

Блоки кода RazorRazor code blocks

Блоки кода Razor начинаются с символа @ и заключены в фигурные скобки {}.Razor code blocks start with @ and are enclosed by {}. В отличие от выражений код C# внутри блоков кода не обрабатывается.Unlike expressions, C# code inside code blocks isn't rendered. Блоки кода и выражения в представлении используют общую область и определяются в следующем порядке:Code blocks and expressions in a view share the same scope and are defined in order:

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

Код отображает следующий HTML:The code renders the following HTML:

<p>The future depends on what you do today. - Mahatma Gandhi</p>
<p>Hate cannot drive out hate, only love can do that. - Martin Luther King, Jr.</p>

В блоках кода объявите локальные функции с помощью разметки для использования в качестве методов создания шаблонов:In code blocks, declare local functions with markup to serve as templating methods:

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

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

Код отображает следующий HTML:The code renders the following HTML:

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

Неявные переходыImplicit transitions

В блоке кода языком по умолчанию является C#, но страница Razor Page может вернуться на HTML:The default language in a code block is C#, but the Razor Page can transition back to HTML:

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

Явный переход с разделителямиExplicit delimited transition

Чтобы определить подраздел блока кода, который должен отрисовывать HTML, окружите подлежащие отображению символы тегами Razor <text>:To define a subsection of a code block that should render HTML, surround the characters for rendering with the Razor <text> tag:

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

Используйте этот способ для отрисовки HTML, не заключенного в HTML-теги.Use this approach to render HTML that isn't surrounded by an HTML tag. Без тега HTML или Razor возникает ошибка времени выполнения Razor.Without an HTML or Razor tag, a Razor runtime error occurs.

Тег <text> хорошо подходит для контроля пробелов при отрисовке содержимого:The <text> tag is useful to control whitespace when rendering content:

  • Отрисовывается только содержимое между тегами <text>.Only the content between the <text> tag is rendered.
  • В выходных данных HTML пробелы до или после тега <text> не отображаются.No whitespace before or after the <text> tag appears in the HTML output.

Явный перенос строкиExplicit line transition

Для отрисовки оставшейся части строки в виде HTML внутри блока кода используйте синтаксис @::To render the rest of an entire line as HTML inside a code block, use @: syntax:

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

Если в коде отсутствует @:, возникает ошибка среды выполнения Razor.Without the @: in the code, a Razor runtime error is generated.

Дополнительные символы @ в файле Razor могут вызвать ошибки компилятора в последующих операторах блока.Extra @ characters in a Razor file can cause compiler errors at statements later in the block. Эти ошибки компилятора может быть трудно проанализировать, так как ошибка фактически возникает раньше, чем указано.These compiler errors can be difficult to understand because the actual error occurs before the reported error. Чаще всего эта ошибка появляется после объединения множества неявных или явных выражений в один блок кода.This error is common after combining multiple implicit/explicit expressions into a single code block.

Управляющие структурыControl structures

Управляющие структуры являются расширением блоков кода.Control structures are an extension of code blocks. Все аспекты блоков кода (переход на разметку, встроенный код C#) также относятся к следующим структурам.All aspects of code blocks (transitioning to markup, inline C#) also apply to the following structures:

Условные выражения @if, else if, else и @switchConditionals @if, else if, else, and @switch

@if контролирует, когда нужно запускать код:@if controls when code runs:

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

Для else и else if символ @ не требуется:else and else if don't require the @ 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>
}

В следующей разметке показано использование оператора switch:The following markup shows how to use a switch statement:

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

Циклы @for, @foreach, @while и @do whileLooping @for, @foreach, @while, and @do while

Операторы выполнения цикла позволяют выполнять отрисовку шаблонного HTML.Templated HTML can be rendered with looping control statements. Отрисовка списка людей:To render a list of people:

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

Поддерживаются следующие операторы выполнения цикла:The following looping statements are supported:

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

Составные @usingCompound @using

В C# оператор using позволяет обеспечить использование какого-то объекта.In C#, a using statement is used to ensure an object is disposed. В Razor этот механизм позволяет создавать вспомогательные функции HTML, включающие дополнительное содержимое.In Razor, the same mechanism is used to create HTML Helpers that contain additional content. В следующем коде вспомогательные функции HTML используют оператор <form> для создания тега @using:In the following code, HTML Helpers render a <form> tag with the @using statement:

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

@try, catch, finally@try, catch, finally

Обработка исключений выполняется так же, как в C#:Exception handling is similar to 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@lock

Razor позволяет защищать важные разделы при помощи операторов блокировки:Razor has the capability to protect critical sections with lock statements:

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

КомментарииComments

Razor поддерживает комментарии C# и HTML:Razor supports C# and HTML comments:

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

Код отображает следующий HTML:The code renders the following HTML:

<!-- HTML comment -->

Сервер удаляет комментарии Razor перед отображением веб-страницы.Razor comments are removed by the server before the webpage is rendered. Для разделения комментариев Razor использует @* *@.Razor uses @* *@ to delimit comments. Следующий код закомментирован, поэтому сервер не отрисовывает разметку:The following code is commented out, so the server doesn't render any markup:

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

ДирективыDirectives

Директивы Razor представлены неявными выражениями с зарезервированными ключевыми словами после символа @.Razor directives are represented by implicit expressions with reserved keywords following the @ symbol. Как правило, директива изменяет способ анализа представления или открывает доступ к дополнительным функциям.A directive typically changes the way a view is parsed or enables different functionality.

Узнав, каким образом Razor создает код для представления, вы сможете легко понять принципы работы директив.Understanding how Razor generates code for a view makes it easier to understand how directives work.

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

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

Код создает класс, аналогичный следующему:The code generates a class similar to the following:

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

Сведения о просмотре этого класса приводятся в разделе Просмотр Razor-класса C#, созданного для представления далее в этой статье.Later in this article, the section Inspect the Razor C# class generated for a view explains how to view this generated class.

@attribute@attribute

Директива @attribute добавляет данный атрибут к классу созданной страницы или представления.The @attribute directive adds the given attribute to the class of the generated page or view. В следующем примере добавляется атрибут [Authorize]:The following example adds the [Authorize] attribute:

@attribute [Authorize]

@code@code

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Блок @code позволяет компоненту Razor добавлять в компонент элементы C# (поля, свойства и методы):The @code block enables a Razor component to add C# members (fields, properties, and methods) to a component:

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

Для компонентов Razor @code является псевдонимом @functions и рекомендуется вместо @functions.For Razor components, @code is an alias of @functions and recommended over @functions. Допускается более одного блока @code.More than one @code block is permissible.

@functions@functions

Директива @functions позволяет добавлять элементы C# (поля, свойства и методы) в создаваемый класс:The @functions directive enables adding C# members (fields, properties, and methods) to the generated class:

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

В компонентах Razor используйте @codeдля добавления членов C# вместо @functions.In Razor components, use @code over @functions to add C# members.

Пример:For example:

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

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

Код создает следующую разметку HTML:The code generates the following HTML markup:

<div>From method: Hello</div>

Следующий код показывает созданный Razor-класс C#:The following code is the generated Razor C# class:

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 служат в качестве методов создания шаблонов при наличии разметки:@functions methods serve as templating methods when they have markup:

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

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

Код отображает следующий HTML:The code renders the following HTML:

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

@implements@implements

Директива @implements реализует интерфейс для созданного класса.The @implements directive implements an interface for the generated class.

В следующем примере реализуется System.IDisposable, чтобы можно было вызывать метод Dispose:The following example implements System.IDisposable so that the Dispose method can be called:

@implements IDisposable

<h1>Example</h1>

@functions {
    private bool _isDisposed;

    ...

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

@inherits@inherits

Директива @inherits позволяет полностью управлять классом, которому наследует представление:The @inherits directive provides full control of the class the view inherits:

@inherits TypeNameOfClassToInheritFrom

Следующий код показывает настраиваемый тип страницы Razor:The following code is a custom Razor page type:

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:The CustomText is displayed in a view:

@inherits CustomRazorPage<TModel>

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

Код отображает следующий HTML:The code renders the following HTML:

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

@model и @inherits могут использоваться в одном представлении.@model and @inherits can be used in the same view. @inherits может находиться в файле _ViewImports.cshtml, который импортируется представлением:@inherits can be in a _ViewImports.cshtml file that the view imports:

@inherits CustomRazorPage<TModel>

Следующий код показывает пример строго типизированного представления:The following code is an example of a strongly-typed view:

@inherits CustomRazorPage<TModel>

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

Если передать в модель "rick@contoso.com", представление создает следующую разметку HTML:If "rick@contoso.com" is passed in the model, the view generates the following 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@inject

Директива @inject позволяет странице Razor внедрять в представление службу из контейнера службы.The @inject directive enables the Razor Page to inject a service from the service container into a view. Дополнительные сведения: Внедрение зависимостей в представления.For more information, see Dependency injection into views.

@layout@layout

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Директива @layout задает макет для компонента Razor.The @layout directive specifies a layout for a Razor component. Компоненты макета используются, чтобы избежать дублирования и несогласованности кода.Layout components are used to avoid code duplication and inconsistency. Дополнительные сведения см. в разделе Макеты Blazor в ASP.NET Core.For more information, see Макеты Blazor в ASP.NET Core.

@model@model

Этот сценарий применяется только к представлениям MVC и Razor Pages (.cshtml).This scenario only applies to MVC views and Razor Pages (.cshtml).

Директива @model определяет тип модели, передаваемой в представление или страницу:The @model directive specifies the type of the model passed to a view or page:

@model TypeNameOfModel

В MVC-приложении ASP.NET Core или Razor Pages, созданном с отдельными учетными записями пользователей, представление Views/Account/Login.cshtml содержит следующее объявление модели:In an ASP.NET Core MVC or Razor Pages app created with individual user accounts, Views/Account/Login.cshtml contains the following model declaration:

@model LoginViewModel

Созданный класс наследует от RazorPage<dynamic>:The class generated inherits from RazorPage<dynamic>:

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Для доступа к модели, переданной в представление, Razor предоставляет свойство Model:Razor exposes a Model property for accessing the model passed to the view:

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

Директива @model задает тип свойства Model.The @model directive specifies the type of the Model property. Директива указывает T в RazorPage<T> — созданном классе, на основе которого создается производное представление.The directive specifies the T in RazorPage<T> that the generated class that the view derives from. Если директива @model не указана, свойство Model имеет тип dynamic.If the @model directive isn't specified, the Model property is of type dynamic. Дополнительные сведения см. в разделе Строго типизированные модели и ключевое слово @model.For more information, see Strongly typed models and the @model keyword.

@namespace@namespace

Директива @namespace:The @namespace directive:

  • задает пространство имен класса созданной страницы Razor, представления MVC или компонента Razor.Sets the namespace of the class of the generated Razor page, MVC view, or Razor component.
  • Устанавливает корневые производные пространства имен страниц, представлений или классов компонентов из ближайшего файла импорта в дереве каталогов, _ViewImports.cshtml (представления или страницы) или _Imports.razor (компоненты Razor).Sets the root derived namespaces of a pages, views, or components classes from the closest imports file in the directory tree, _ViewImports.cshtml (views or pages) or _Imports.razor (Razor components).
@namespace Your.Namespace.Here

Для примера Razor Pages, приведенного в следующей таблице:For the Razor Pages example shown in the following table:

  • Каждая страница импортирует Pages/_ViewImports.cshtml.Each page imports Pages/_ViewImports.cshtml.
  • Файл Pages/_ViewImports.cshtml содержит @namespace Hello.World.Pages/_ViewImports.cshtml contains @namespace Hello.World.
  • Каждая страница имеет Hello.World в качестве корня пространства имен.Each page has Hello.World as the root of it's namespace.
СтраницаPage Пространство именNamespace
Pages/Index.cshtmlPages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtmlPages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtmlPages/MorePages/EvenMorePages/Page.cshtml Hello.World.MorePages.EvenMorePages

Описанные отношения применяются к файлам импорта, которые используются в представлениях MVC и компонентах Razor.The preceding relationships apply to import files used with MVC views and Razor components.

Если у нескольких файлов импорта есть директива @namespace, для задания корневого пространства имен используется файл, ближайший к странице, компоненту или представлению в дереве каталогов.When multiple import files have a @namespace directive, the file closest to the page, view, or component in the directory tree is used to set the root namespace.

Если папка EvenMorePages в предыдущем примере содержит файл импорта с @namespace Another.Planet (или же файл Pages/MorePages/EvenMorePages/Page.cshtml содержит @namespace Another.Planet), результат отображается в следующей таблице.If the EvenMorePages folder in the preceding example has an imports file with @namespace Another.Planet (or the Pages/MorePages/EvenMorePages/Page.cshtml file contains @namespace Another.Planet), the result is shown in the following table.

СтраницаPage Пространство именNamespace
Pages/Index.cshtmlPages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtmlPages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtmlPages/MorePages/EvenMorePages/Page.cshtml Another.Planet

@page@page

Директива @page имеет различные эффекты в зависимости от типа файла, в котором она используется.The @page directive has different effects depending on the type of the file where it appears. Директива:The directive:

Директива @page в первой строке .cshtml-файла указывает, что файл является страницей Razor.The @page directive on the first line of a .cshtml file indicates that the file is a Razor Page. Дополнительные сведения см. в разделе Введение в Razor Pages в ASP.NET Core.For more information, see Введение в Razor Pages в ASP.NET Core.

@section@section

Этот сценарий применяется только к представлениям MVC и Razor Pages (.cshtml).This scenario only applies to MVC views and Razor Pages (.cshtml).

Директива @section используется в сочетании с макетами MVC и Razor Pages и позволяет представлениям и страницам отображать содержимое в различных частях HTML-страницы.The @section directive is used in conjunction with MVC and Razor Pages layouts to enable views or pages to render content in different parts of the HTML page. Дополнительные сведения см. в разделе Макет в ASP.NET Core.For more information, see Макет в ASP.NET Core.

@using@using

Директива @using добавляет директиву C# using в созданное представление:The @using directive adds the C# using directive to the generated view:

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

В компонентах Razor@usingтакже определяет, какие компоненты находятся в области.In Razor components, @using also controls which components are in scope.

Атрибуты директивыDirective attributes

@attributes@attributes

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

@attributes позволяет компоненту обрабатывать необъявленные атрибуты.@attributes allows a component to render non-declared attributes. Дополнительные сведения см. в разделе Создание и использование компонентов Razor ASP.NET Core.For more information, see Создание и использование компонентов Razor ASP.NET Core.

@bind@bind

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Привязка данных в компонентах выполняется с помощью атрибута @bind.Data binding in components is accomplished with the @bind attribute. Дополнительные сведения см. в разделе Привязка к данным в ASP.NET Core Blazor.For more information, see Привязка к данным в ASP.NET Core Blazor.

@on{СОБЫТИЕ}@on{EVENT}

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Razor предоставляет функции обработки событий для компонентов.Razor provides event handling features for components. Дополнительные сведения см. в разделе Обработка событий Blazor в ASP.NET Core.For more information, see Обработка событий Blazor в ASP.NET Core.

@on{СОБЫТИЕ}:preventDefault@on{EVENT}:preventDefault

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Запрещает выполнение действия по умолчанию для события.Prevents the default action for the event.

@on{СОБЫТИЕ}:stopPropagation@on{EVENT}:stopPropagation

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Останавливает распространение события.Stops event propagation for the event.

@key@key

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Атрибут директивы @key заставляет алгоритм сравнения компонентов гарантировать сохранение элементов или компонентов на основе значения ключа.The @key directive attribute causes the components diffing algorithm to guarantee preservation of elements or components based on the key's value. Дополнительные сведения см. в разделе Создание и использование компонентов Razor ASP.NET Core.For more information, see Создание и использование компонентов Razor ASP.NET Core.

@ref@ref

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Ссылки на компоненты (@ref) предоставляют способ ссылаться на экземпляр компонента, чтобы можно было выполнять команды для этого экземпляра.Component references (@ref) provide a way to reference a component instance so that you can issue commands to that instance. Дополнительные сведения см. в разделе Создание и использование компонентов Razor ASP.NET Core.For more information, see Создание и использование компонентов Razor ASP.NET Core.

@typeparam@typeparam

Этот сценарий применяется только к компонентам Razor (.razor).This scenario only applies to Razor components (.razor).

Директива @typeparam объявляет параметр универсального типа для созданного класса компонента.The @typeparam directive declares a generic type parameter for the generated component class. Дополнительные сведения см. в разделе Шаблонные компоненты Blazor в ASP.NET Core.For more information, see Шаблонные компоненты Blazor в ASP.NET Core.

Шаблонные делегаты RazorTemplated Razor delegates

Шаблоны Razor позволяют определить фрагмент кода пользовательского интерфейса в следующем формате:Razor templates allow you to define a UI snippet with the following format:

@<tag>...</tag>

Следующий пример показывает, как указать шаблонный делегат Razor в виде Func<T,TResult>.The following example illustrates how to specify a templated Razor delegate as a Func<T,TResult>. Динамический тип указывается для параметра метода, инкапсулируемого делегатом.The dynamic type is specified for the parameter of the method that the delegate encapsulates. Тип объекта указывается в качестве возвращаемого значения делегата.An object type is specified as the return value of the delegate. Этот шаблон используется с List<T>объекта Pet, имеющим свойство Name.The template is used with a List<T> of Pet that has a Name property.

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

Шаблон отрисовывается с использованием pets, предоставляемого оператором foreach:The template is rendered with pets supplied by a foreach statement:

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

Отображенные выходные данные:Rendered output:

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

Вы также можете предоставить встроенный шаблон Razor в качестве аргумента для метода.You can also supply an inline Razor template as an argument to a method. В следующем примере метод Repeat получает шаблон Razor.In the following example, the Repeat method receives a Razor template. Метод использует этот шаблон для создания HTML-содержимого с повторениями элементов из списка:The method uses the template to produce HTML content with repeats of items supplied from a list:

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

С использованием списка домашних животных из предыдущего примера метод Repeat вызывается следующим образом:Using the list of pets from the prior example, the Repeat method is called with:

  • List<T> объекта Pet.List<T> of Pet.
  • Количество повторений для каждого домашнего животного.Number of times to repeat each pet.
  • Встроенный шаблон, используемый для перечисления элементов неупорядоченного списка.Inline template to use for the list items of an unordered list.
<ul>
    @Repeat(pets, 3, @<li>@item.Name</li>)
</ul>

Отображенные выходные данные:Rendered output:

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

Вспомогательные функции теговTag Helpers

Этот сценарий применяется только к представлениям MVC и Razor Pages (.cshtml).This scenario only applies to MVC views and Razor Pages (.cshtml).

Существует три директивы, которые относятся к вспомогательным функциям тегов.There are three directives that pertain to Tag Helpers.

ДирективаDirective КомпонентFunction
@addTagHelper Делает вспомогательные функции тегов доступными в представлении.Makes Tag Helpers available to a view.
@removeTagHelper Удаляет из представления вспомогательные функции тегов, добавленные ранее.Removes Tag Helpers previously added from a view.
@tagHelperPrefix Задает префикс тега, который активирует поддержку вспомогательной функции тега и ее использования в явном виде.Specifies a tag prefix to enable Tag Helper support and to make Tag Helper usage explicit.

Зарезервированные ключевые слова RazorRazor reserved keywords

Ключевые слова RazorRazor keywords

  • page (требуется ASP.NET Core 2.1 или более поздней версии)page (Requires ASP.NET Core 2.1 or later)
  • пространство именnamespace
  • functionsfunctions
  • наследуетinherits
  • modelmodel
  • sectionsection
  • helper (сейчас не поддерживается в ASP.NET Core)helper (Not currently supported by ASP.NET Core)

В качестве escape-символа для ключевых слов Razor используется @(Razor Keyword) (например, @(functions)).Razor keywords are escaped with @(Razor Keyword) (for example, @(functions)).

Ключевые слова C# в RazorC# Razor keywords

  • casecase
  • dodo
  • значение по умолчаниюdefault
  • forfor
  • foreachforeach
  • ifif
  • elseelse
  • locklock
  • Параметрswitch
  • попробуйте выполнить следующееtry
  • catchcatch
  • finallyfinally
  • С помощьюusing
  • whilewhile

Для ключевых слов C# в Razor требуется двойной escape-символ: @(@C# Razor Keyword) (например, @(@case)).C# Razor keywords must be double-escaped with @(@C# Razor Keyword) (for example, @(@case)). Первый @ предназначен для обхода синтаксического анализа Razor,The first @ escapes the Razor parser. а второй @ — для обхода C#.The second @ escapes the C# parser.

Зарезервированные ключевые слова, не используемые в RazorReserved keywords not used by Razor

  • classclass

Просмотр Razor-класса C#, созданного для представленияInspect the Razor C# class generated for a view

При использовании пакета SDK для .NET Core 2.1 или более поздней версии пакет SDK для Razor обрабатывает компиляцию файлов Razor.With .NET Core SDK 2.1 or later, the Razor SDK handles compilation of Razor files. При сборке проекта пакет SDK для Razor создает каталог obj/<конфигурация_сборки>/<моникер_целевой_платформы>/Razor в корневом каталоге проекта.When building a project, the Razor SDK generates an obj/<build_configuration>/<target_framework_moniker>/Razor directory in the project root. Структура каталогов в каталоге Razor отражает структуру каталогов проекта.The directory structure within the Razor directory mirrors the project's directory structure.

Рассмотрим следующую структуру каталогов в проекте ASP.NET Core 2.1 Razor Pages, предназначенном для .NET Core 2.1.Consider the following directory structure in an ASP.NET Core 2.1 Razor Pages project targeting .NET Core 2.1:

  • Areas/Areas/
    • Admin/Admin/
      • Pages/Pages/
        • Index.cshtmlIndex.cshtml
        • Index.cshtml.csIndex.cshtml.cs
  • Pages/Pages/
    • Shared/Shared/
      • _Layout.cshtml_Layout.cshtml
    • _ViewImports.cshtml_ViewImports.cshtml
    • _ViewStart.cshtml_ViewStart.cshtml
    • Index.cshtmlIndex.cshtml
    • Index.cshtml.csIndex.cshtml.cs

При сборке проекта в конфигурации Отладка создается следующий каталог obj:Building the project in Debug configuration yields the following obj directory:

  • obj/obj/
    • Debug/Debug/
      • netcoreapp2.1/netcoreapp2.1/
        • Razor/Razor/
          • Areas/Areas/
            • Admin/Admin/
              • Pages/Pages/
                • Index.g.cshtml.csIndex.g.cshtml.cs
          • Pages/Pages/
            • Shared/Shared/
              • _Layout.g.cshtml.cs_Layout.g.cshtml.cs
            • _ViewImports.g.cshtml.cs_ViewImports.g.cshtml.cs
            • _ViewStart.g.cshtml.cs_ViewStart.g.cshtml.cs
            • Index.g.cshtml.csIndex.g.cshtml.cs

Чтобы просмотреть созданный класс для Pages/Index.cshtml откройте obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs.To view the generated class for Pages/Index.cshtml, open obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs.

Добавьте в MVC-проект ASP.NET следующий класс:Add the following class to the ASP.NET Core MVC project:

using Microsoft.AspNetCore.Mvc.Razor.Extensions;
using Microsoft.AspNetCore.Razor.Language;

public class CustomTemplateEngine : MvcRazorTemplateEngine
{
    public CustomTemplateEngine(RazorEngine engine, RazorProject project) 
        : base(engine, project)
    {
    }
        
    public override RazorCSharpDocument GenerateCode(RazorCodeDocument codeDocument)
    {
        var csharpDocument = base.GenerateCode(codeDocument);
        var generatedCode = csharpDocument.GeneratedCode;

        // Look at generatedCode

        return csharpDocument;
    }
}

В Startup.ConfigureServices переопределите класс RazorTemplateEngine, добавленный MVC, классом CustomTemplateEngine:In Startup.ConfigureServices, override the RazorTemplateEngine added by MVC with the CustomTemplateEngine class:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSingleton<RazorTemplateEngine, CustomTemplateEngine>();
}

Установите точку останова в операторе return csharpDocument; класса CustomTemplateEngine.Set a breakpoint on the return csharpDocument; statement of CustomTemplateEngine. Когда выполнение программы остановится в этой точке, просмотрите значение generatedCode.When program execution stops at the breakpoint, view the value of generatedCode.

Представление generatedCode в визуализаторе текста

Поиск данных в представлениях и учет регистраView lookups and case sensitivity

Модуль представлений Razor позволяет искать в представлениях данные с учетом регистра.The Razor view engine performs case-sensitive lookups for views. Однако фактический поиск зависит от используемой файловой системы.However, the actual lookup is determined by the underlying file system:

  • Источники в виде файлов:File based source:
    • В операционных системах, файловые системы которых не учитывают регистр (например, Windows), поиск поставщика физических файлов не зависит от регистра.On operating systems with case insensitive file systems (for example, Windows), physical file provider lookups are case insensitive. Например, поиск по return View("Test") выводит совпадения /Views/Home/Test.cshtml, /Views/home/test.cshtml и другие варианты с различными сочетаниями регистра.For example, return View("Test") results in matches for /Views/Home/Test.cshtml, /Views/home/test.cshtml, and any other casing variant.
    • В файловых системах, учитывающих регистр (например, в Linux, OSX и где используется EmbeddedFileProvider), поиск выполняется с учетом регистра.On case-sensitive file systems (for example, Linux, OSX, and with EmbeddedFileProvider), lookups are case-sensitive. Например, поиск по return View("Test") дает точное совпадение /Views/Home/Test.cshtml.For example, return View("Test") specifically matches /Views/Home/Test.cshtml.
  • Предварительно скомпилированные представления: в ASP.NET Core 2.0 и более поздних версиях поиск в предварительно скомпилированных представлениях выполняется без учета регистра во всех операционных системах.Precompiled views: With ASP.NET Core 2.0 and later, looking up precompiled views is case insensitive on all operating systems. Это поведение аналогично поведению поставщика физических файлов в Windows.The behavior is identical to physical file provider's behavior on Windows. Если два предварительно скомпилированных представления отличаются только регистром, результат поиска является недетерминированным.If two precompiled views differ only in case, the result of lookup is non-deterministic.

Разработчикам рекомендуется использовать для файлов и каталогов тот же регистр, что и для:Developers are encouraged to match the casing of file and directory names to the casing of:

  • имен областей, контроллеров и действий;Area, controller, and action names.
  • страниц Razor Pages.Razor Pages.

Совпадающий регистр гарантирует, что развертываемые службы смогут находить свои представления вне зависимости от используемой файловой системы.Matching case ensures the deployments find their views regardless of the underlying file system.