Razor ASP.NET Core 的语法参考Razor syntax reference for ASP.NET Core

作者: Rick AndersonTaylor MullenDan VicarelBy 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 的文件的扩展名为 ...Files containing Razor generally have a .cshtml file extension. Razor还可在 Razor 组件文件 () 中找到。Razor is also found in Razor components files (.razor).

呈现 HTMLRendering HTML

默认 Razor 语言为 HTML。The default Razor language is HTML. 从标记呈现 HTML 与 Razor 从 html 文件呈现 html 没有什么不同。Rendering HTML from Razor markup is no different than rendering HTML from an HTML file. 在中, cshtml文件中的 HTML 标记 Razor 不变。HTML markup in .cshtml Razor files is rendered by the server unchanged.

Razor 语法Razor 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#.

若要对 @ 标记中的符号进行转义 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>

隐式 Razor 表达式Implicit 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.

显式 Razor 表达式Explicit 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. 计算结果为 IHtmlContent 的 C# 表达式直接通过 IHtmlContent.WriteTo 呈现。C# expressions that evaluate to IHtmlContent are rendered directly through IHtmlContent.WriteTo. 计算结果不为 IHtmlContent 的 C# 表达式通过 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 preceding code renders the following HTML:

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

HTML 在浏览器中显示为纯文本:The HTML is shown in the browser as plain text:

<跨越 > Hello World < /span><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.RawAvoid using HtmlHelper.Raw with user input.

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

该代码呈现以下 HTML:The code renders the following HTML:

<span>Hello World</span>

Razor 代码块Razor 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 页面可转换回 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.
  • <text> 标记之前或之后的空格不会显示在 HTML 输出中。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, and @switchConditionals @if, else if, else, and @switch

@if 控制何时运行代码:@if controls when code runs:

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

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

Hal @for, @foreach, @while, and @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 帮助程序使用 @using 语句呈现 <form> 标记: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

异常处理与 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

Razor 能够用 lock 语句保护关键部分: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 指令将给定的属性添加到生成的页或视图的类中。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

此方案仅适用于 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 建议使用 @functionsFor Razor components, @code is an alias of @functions and recommended over @functions. 允许多个 @code 块。More than one @code block is permissible.

@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 Over @functions 来添加 c # 成员。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 指令为生成的类实现接口。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 指令对视图继承的类提供完全控制: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指令使 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

此方案仅适用于 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. 有关详细信息,请参阅 ASP.NET Core Blazor 布局For more information, see ASP.NET Core Blazor 布局.

@model

此方案仅适用于 Razor () 的 MVC 视图和页面。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

在 Razor 使用单独的用户帐户创建的 ASP.NET CORE MVC 或页面应用中, 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. 该指令将 RazorPage<T> 中的 T 指定为生成的类,视图便派生自该类。The directive specifies the T in RazorPage<T> that the generated class that the view derives from. 如果未指定 @model 指令,则 Model 属性的类型为 dynamicIf 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 指令:The @namespace directive:

  • 设置生成的 Razor 页、MVC 视图或组件的类的命名空间 Razor 。Sets the namespace of the class of the generated Razor page, MVC view, or Razor component.
  • 在目录树中最近的导入文件中设置页面、视图或组件类的根派生命名空间, _ViewImports) 或 _Imports razor (组件) (视图或页面。 RazorSets 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 下表中所示的页面示例: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.
PagePage 命名空间Namespace
Pages/Index. cshtmlPages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml**Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml**Pages/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.

PagePage 命名空间Namespace
Pages/Index. cshtmlPages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml**Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml**Pages/MorePages/EvenMorePages/Page.cshtml Another.Planet

@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. 有关详细信息,请参阅 ASP.NET Core 中的 Razor Pages 介绍For more information, see ASP.NET Core 中的 Razor Pages 介绍.

@section

此方案仅适用于 Razor () 的 MVC 视图和页面。This scenario only applies to MVC views and Razor Pages (.cshtml).

@section指令与MVC 和 Razor 页面布局结合使用,以使视图或页面能够在 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 指令用于向生成的视图添加 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

Razor 指令特性由带有符号后的保留关键字的隐式表达式表示 @Razor directive attributes are represented by implicit expressions with reserved keywords following the @ symbol. 指令特性通常会改变元素的分析方式,或实现不同的功能。A directive attribute typically changes the way an element is parsed or enables different functionality.

@attributes

此方案仅适用于 Razor ( razor) 的组件。This scenario only applies to Razor components (.razor).

@attributes 允许组件呈现未声明的属性。@attributes allows a component to render non-declared attributes. 有关详细信息,请参阅 创建和使用 ASP.NET Core Razor 组件For more information, see 创建和使用 ASP.NET Core Razor 组件.

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

此方案仅适用于 Razor ( razor) 的组件。This scenario only applies to Razor components (.razor).

Razor 为组件提供事件处理功能。Razor provides event handling features for components. 有关详细信息,请参阅 ASP.NET Core Blazor 事件处理For more information, see ASP.NET Core Blazor 事件处理.

@on{EVENT}:preventDefault

此方案仅适用于 Razor ( razor) 的组件。This scenario only applies to Razor components (.razor).

禁止事件的默认操作。Prevents the default action for the event.

@on{EVENT}:stopPropagation

此方案仅适用于 Razor ( razor) 的组件。This scenario only applies to Razor components (.razor).

停止事件的事件传播。Stops event propagation for the event.

@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. 有关详细信息,请参阅 创建和使用 ASP.NET Core Razor 组件For more information, see 创建和使用 ASP.NET Core Razor 组件.

@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. 有关详细信息,请参阅 创建和使用 ASP.NET Core Razor 组件For more information, see 创建和使用 ASP.NET Core Razor 组件.

@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. 有关详细信息,请参阅 ASP.NET Core Blazor 模板化组件For more information, see ASP.NET Core Blazor 模板化组件.

模板化 Razor 委托Templated Razor delegates

Razor 模板允许使用以下格式定义 UI 代码段: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. 该模板与 Pet(具有 Name 属性)的 List<T> 一起使用。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" }
    };
}

使用 foreach 语句提供的 pets 呈现该模板: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;
    }
}

使用前面示例中的 pets 列表,调用 Repeat 方法以及:Using the list of pets from the prior example, the Repeat method is called with:

  • PetList<T>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

此方案仅适用于 Razor () 的 MVC 视图和页面。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.

Razor 保留关键字Razor reserved keywords

Razor 字Razor keywords

  • page (要求 ASP.NET Core 2.1 或更高版本) page (Requires ASP.NET Core 2.1 or later)
  • namespace
  • functions
  • inherits
  • model
  • section
  • helper ASP.NET Core 当前不支持 () helper (Not currently supported by ASP.NET Core)

Razor 关键字通过 @(Razor Keyword) (进行转义,例如 @(functions)) 。Razor keywords are escaped with @(Razor Keyword) (for example, @(functions)).

C # Razor 关键字C# Razor keywords

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

C # Razor 关键字必须用 @(@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

  • class

检查 Razor 为视图生成的 c # 类Inspect the Razor C# class generated for a view

对于 .NET Core SDK 2.1 或更高版本, Razor SDK会处理 Razor 文件的编译。With .NET Core SDK 2.1 or later, the Razor SDK handles compilation of Razor files. 生成项目时,SDK 会 Razor 在项目根目录中生成一个 <build_configuration>/<target_framework_moniker> 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.

请考虑面向 .NET Core 2.1 的 ASP.NET Core 2.1 页项目中的以下目录结构 Razor :Consider the following directory structure in an ASP.NET Core 2.1 Razor Pages project targeting .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

在 Debug 配置下生成项目将生成以下 obj 目录****:Building the project in Debug configuration yields the following obj directory:

 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

若要查看 页面/索引生成的类,请打开 obj/Debug/netcoreapp 2.1/ Razor /Pages/Index.g.cshtml.csTo view the generated class for Pages/Index.cshtml, open obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs.

将下面的类添加到 ASP.NET Core MVC 项目:Add the following class to the ASP.NET Core MVC project:

#if V2
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;
    }
}
#endif

Startup.ConfigureServices 中,使用 CustomTemplateEngine 类替代 MVC 添加的 RazorTemplateEngineIn Startup.ConfigureServices, override the RazorTemplateEngine added by MVC with the CustomTemplateEngine class:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

CustomTemplateEnginereturn csharpDocument; 语句上设置断点。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.cshtmlFor 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 页.Razor Pages.

匹配大小写可确保无论使用哪种基础文件系统,部署都能找到其视图。Matching case ensures the deployments find their views regardless of the underlying file system.

其他资源Additional resources

使用 Razor ASP.NET Web 编程简介语法 提供了许多用语法编程的示例 Razor 。Introduction to ASP.NET Web Programming Using the Razor Syntax provides many samples of programming with Razor syntax.