ASP.NET Core 的 Razor 語法參考Razor syntax reference for ASP.NET Core

作者:Rick AndersonLuke LathamTaylor MullenDan VicarelBy Rick Anderson, Luke Latham, 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.

轉譯 HTMLRendering HTML

Razor 語言預設為 HTML。The default Razor language is HTML. 轉譯 Razor 標記中的 HTML 與轉譯 HTML 檔案中的 HTML 並無不同。Rendering HTML from Razor markup is no different than rendering HTML from an HTML file. 伺服器會依原狀轉譯 .cshtml Razor 檔案中的 HTML 標記。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' 轉換成非委派類型 'type'。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 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.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 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.
  • <text> 標籤前後不能有空白字元出現在 HTML 輸出中。No whitespace before or after the <text> tag appears in the HTML output.

使用 @ 的明確行轉換:Explicit Line Transition with @:

若要將一整行的其餘部分轉譯為程式碼區塊內的 HTML,請使用 @: 語法:To render the rest of an entire line as HTML inside a code block, use the @: 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 檔案中的額外 @ 字元可能會導致稍後在區塊的陳述式中發生編譯器錯誤。Warning: 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>
}

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

迴圈 @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 協助程式使用 @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>
}

範圍層級動作可以透過標籤協助程式來執行。Scope-level actions can be performed with Tag Helpers.

@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

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.

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

@model

@model 指示詞會指定傳遞至檢視的模型類型:The @model directive specifies the type of the model passed to a view:

@model TypeNameOfModel

在使用個別使用者帳戶建立的 ASP.NET Core MVC 應用程式中,Views/Account/Login.cshtml 檢視包含下列模型宣告:In an ASP.NET Core MVC app created with individual user accounts, the Views/Account/Login.cshtml view 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 指示詞會指定此屬性的類型。The @model directive specifies the type of this 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. 模型的值會從控制器傳遞至檢視。The value of the model is passed from the controller to the view. 如需詳細資訊,請參閱強型別模型和 @model 關鍵字For more information, see Strongly typed models and the @model keyword.

@inherits

@inherits 指示詞可讓您完全控制檢視所繼承的類別:The @inherits directive provides full control of the class the view inherits:

@inherits TypeNameOfClassToInheritFrom

下列程式碼是自訂 Razor Page 類型: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 Page 從服務容器將服務插入至檢視。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.

@functions

@functions 指示詞可讓 Razor 頁面將 C# 程式碼區塊新增至檢視:The @functions directive enables a Razor Page to add a C# code block to a view:

@functions { // C# Code }

例如: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>

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

警告

ASP.NET Core 3.0 Preview 6 版本中的已知問題:@attribute 指示詞在 _Imports.razor_ViewImports.cshtml 檔案中沒有作用。In ASP.NET Core 3.0 Preview 6 release, there's a known issue where @attribute directives don't work in _Imports.razor and _ViewImports.cshtml files. Preview 7 版本會解決此問題。This will be addressed in the Preview 7 release.

@namespace

@namespace 指示詞會設定所產生頁面或檢視類別的命名空間:The @namespace directive sets the namespace of the class of the generated page or view:

@namespace Your.Namespace.Here

如果頁面或檢視匯入具有 @namespace 指示詞的 API,則原始檔案的命名空間會設定為相對於該命名空間。If a page or view imports API with an @namespace directive, the original file's namespace is set relative to that namespace.

如果 MyApp/Pages/_ViewImports.cshtml 包含 @namespace Hello.World,則匯入 Hello.World 命名空間的網頁或檢視命名空間會如下表設定。If MyApp/Pages/_ViewImports.cshtml contains @namespace Hello.World, the namespace of pages or views that import the Hello.World namespace is set as shown in the following table.

頁面 (或檢視)Page (or view) 命名空間Namespace
MyApp/Pages/Index.cshtmlMyApp/Pages/Index.cshtml Hello.World
MyApp/Pages/MorePages/Bar.cshtmlMyApp/Pages/MorePages/Bar.cshtml Hello.World.MorePages

如果多個匯入檔案都有 @namespace 指示詞,則會使用目錄鏈結中最接近網頁或檢視的檔案。If multiple import files have the @namespace directive, the file closest to the page or view in the directory chain is used.

@section

@section 指示詞可搭配配置使用,讓網頁或檢視可以轉譯 HTML 頁面中不同部分中的內容。The @section directive is used in conjunction with the layout to enable pages or views to render content in different parts of the HTML page. 如需詳細資訊,請參閱區段For more information, see Sections.

樣板化 Razor 委派Templated Razor delegates

Razor 範本可讓您使用下列格式定義 UI 程式碼片段:Razor templates allow you to define a UI snippet with the following format:

@<tag>...</tag>

下列範例說明如何以 Func<T,TResult> 的形式指定樣板化 Razor 委派。The following example illustrates how to specify a templated Razor delegate as a Func<T,TResult>. 該範例會指定 dynamic 類型作為委派所封裝方法的參數。The dynamic type is specified for the parameter of the method that the delegate encapsulates. 並指定 object 類型作為委派的傳回值。An object type is specified as the return value of the delegate. 此範本會搭配具有 Name 屬性之 PetList<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;
    }
}

使用先前範例中的寵物清單,呼叫 Repeat 方法並指定:Using the list of pets from the prior example, the Repeat method is called with:

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

標籤協助程式有三個相關的指示詞。There are three directives that pertain to Tag Helpers.

指示詞Directive 功能Function
@addTagHelper@addTagHelper 使標籤協助程式可供檢視。Makes Tag Helpers available to a view.
@removeTagHelper@removeTagHelper 移除先前從檢視新增的標籤協助程式。Removes Tag Helpers previously added from a view.
@tagHelperPrefix@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.0 和更新版本)page (Requires ASP.NET Core 2.0 and later)
  • namespacenamespace
  • 函式functions
  • 繼承inherits
  • modelmodel
  • sectionsection
  • 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

  • casecase
  • dodo
  • defaultdefault
  • forfor
  • foreachforeach
  • ifif
  • elseelse
  • locklock
  • switchswitch
  • trytry
  • catchcatch
  • finallyfinally
  • usingusing
  • whilewhile

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.

Razor 未使用的保留關鍵字Reserved keywords not used by Razor

  • Class - 類別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. 建置專案時,Razor SDK 會在專案根目錄中產生 obj/<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 Pages 專案中的下列目錄結構: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

Debug 設定中建置專案會產生下列 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.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:

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 中,將 MVC 所新增的 RazorTemplateEngine 覆寫為 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>();
}

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 Pages。Razor Pages.

比對大小寫可確保不論基礎檔案系統為何,部署作業都能夠找到其值。Matching case ensures the deployments find their views regardless of the underlying file system.