ASP.NET Core 的 Razor 語法參考

作者:Rick AndersonTaylor MullenDan Vicarel

Razor 是將 .NET 型程式碼內嵌至網頁的標記語法。 Razor 語法由 Razor 標記、C# 和 HTML 所組成。 包含 Razor 的檔案通常具有 .cshtml 副檔名。 您也可以在 Razor 元件 檔案 (.razor) 中找到 Razor。 Razor 語法類似於各種 JavaScript 單頁應用程式 (SPA) 架構的範本化引擎,例如 Angular、React、VueJs 和 Svelte。 如需詳細資訊,請參閱本文所述的功能從 ASP.NET Core 3.0 開始已過時

使用 Razor 語法進行 ASP.NET Web 程式設計的簡介提供了許多使用 Razor 語法進行程式設計的範例。 雖然本主題是針對 ASP.NET 而不是 ASP.NET Core 所撰寫,但大部分範例也適用於 ASP.NET Core。

轉譯 HTML

預設 Razor 語言為 HTML。 轉譯 Razor 標記中的 HTML 與轉譯 HTML 檔案中的 HTML 並無不同。 伺服器會依原狀轉譯 .cshtmlRazor 檔案中的 HTML 標記。

Razor 語法

Razor 支援 C#,並使用 @ 符號從 HTML 轉換成 C#。 Razor 會評估 C# 運算式並在 HTML 輸出中轉譯這些運算式。

@ 符號後面接著 Razor 保留關鍵字時,其會轉換成 Razor 特定標記。 否則會轉換成一般 HTML。

若要將 Razor 標記中的 @ 符號逸出,請使用第二個 @ 符號:

<p>@@Username</p>

此程式碼在 HTML 中是使用單一 @ 符號轉譯:

<p>@Username</p>

HTML 屬性及含有電子郵件地址的內容不會將 @ 符號視為轉換字元。 Razor 剖析會將下列範例中的電子郵件地址保持不變:

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

可縮放向量圖形 (SVG)

支援 SVGforeignObject 元素:

@{
    string message = "foreignObject example with Scalable Vector Graphics (SVG)";
}

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <rect x="0" y="0" rx="10" ry="10" width="200" height="200" stroke="black" 
        fill="none" />
    <foreignObject x="20" y="20" width="160" height="160">
        <p>@message</p>
    </foreignObject>
</svg>

隱含的 Razor 運算式

隱含的 Razor 運算式會以 @ 開頭,後面接著 C# 程式碼:

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

除了 C# await 關鍵字以外,隱含運算式不能包含空格。 如果 C# 陳述式具有明確的結束字元,則可以混合空格:

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

隱含運算式「不能」包含 C# 泛型,因為括弧 (<>) 內的字元會解譯為 HTML 標籤。 下列程式碼無效

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

上述程式碼會產生類似下列其中一項的編譯器錯誤:

  • "Int" 項目未關閉。 所有項目都必須自行結束或具有相對應的結束標籤。
  • 無法將方法群組 'GenericMethod' 轉換成非委派類型 'type'。 您是否想要叫用方法?

泛型方法呼叫必須包裝在明確的 Razor 運算式Razor 程式碼區塊中。

明確的 Razor 運算式

明確的 Razor 運算式由 @ 符號與對稱的括弧所組成。 為了轉譯上週的時間,使用了下列 Razor 標記:

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

@() 括弧內的任何內容都會經過評估並轉譯成輸出。

上一節中所述的隱含運算式通常不能包含空格。 在下列程式碼中,不會從目前的時間減去一週:

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

程式碼會轉譯下列 HTML:

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

明確運算式可用來串連文字與運算式結果:

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

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

若沒有明確運算式,<p>Age@joe.Age</p> 會視為電子郵件地址,並轉譯 <p>Age@joe.Age</p>。 當撰寫為明確運算式時,會轉譯 <p>Age33</p>

明確運算式可以用來轉譯 .cshtml 檔案中泛型方法的輸出。 下列標記會顯示如何修正稍早顯示的錯誤,此錯誤是由 C# 泛型的括弧所造成。 程式碼會撰寫為明確運算式:

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

運算式編碼

評估為字串的 C# 運算式會以 HTML 編碼。 評估為 IHtmlContent 的 C# 運算式會透過 IHtmlContent.WriteTo 直接轉譯。 未評估為 IHtmlContent 的 C# 運算式會由 ToString 轉換成字串,並經過編碼再轉譯。

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

上述程式碼會轉譯下列 HTML:

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

此 HTML 在瀏覽器中會顯示為純文字:

<span>Hello World</span>

HtmlHelper.Raw 輸出不會經過編碼,而是轉譯為 HTML 標記。

警告

對未清理的使用者輸入使用 HtmlHelper.Raw 會造成安全性風險。 使用者輸入可能包含惡意的 JavaScript 或其他惡意探索。 清理使用者輸入並不容易。 請避免對使用者輸入使用 HtmlHelper.Raw

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

程式碼會轉譯下列 HTML:

<span>Hello World</span>

Razor 程式碼區塊

Razor 程式碼區塊會以 @ 開頭,並以 {} 括住。 不同於運算式,程式碼區塊內的 C# 程式碼不會轉譯。 一個檢視中的程式碼區塊和運算式會共用相同的範圍並依序定義:

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

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

在程式碼區塊中,使用標記宣告區域函式作為樣板化方法:

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

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

程式碼會轉譯下列 HTML:

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

隱含轉換

程式碼區塊中的預設語言是 C#,但 Razor Page 可以轉換回 HTML:

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

明確分隔的轉換

若要定義程式碼區塊中應轉譯 HTML 的子區段,請使用 Razor<text> 標籤括住要轉譯的字元:

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

使用此方法可轉譯未以 HTML 標籤括住的 HTML。 若沒有 HTML 或 Razor 標籤,就會發生 Razor 執行階段錯誤。

<text> 標籤可在轉譯內容時用來控制空白字元:

  • 只會轉譯 <text> 標籤之間的內容。
  • 在 HTML 輸出中,<text> 標籤前後都不能出現任何空白字元。

明確的行轉換

若要將一整行的其餘部分轉譯為程式碼區塊內的 HTML,請使用 @: 語法:

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

若程式碼中沒有 @:,就會產生 Razor 執行階段錯誤。

Razor 檔案中的額外 @ 字元可能會導致稍後在區塊的陳述式中發生編譯器錯誤。 這些額外的 @ 編譯器錯誤:

  • 可能很難了解,因為實際錯誤發生在回報的錯誤之前。
  • 將多個明確/隱含運算式合併成單一程式碼區塊之後,經常會出現此情況。

條件式屬性轉譯

Razor 會自動省略不需要的屬性。 如果傳入的值是 nullfalse,則不會轉譯屬性。

例如,請參慮下列 razor:

<div class="@false">False</div>
<div class="@null">Null</div>
<div class="@("")">Empty</div>
<div class="@("false")">False String</div>
<div class="@("active")">String</div>
<input type="checkbox" checked="@true" name="true" />
<input type="checkbox" checked="@false" name="false" />
<input type="checkbox" checked="@null" name="null" />

上述 Razor 標記會產生下列 HTML:

<div>False</div>
<div>Null</div>
<div class="">Empty</div>
<div class="false">False String</div>
<div class="active">String</div>
<input type="checkbox" checked="checked" name="true">
<input type="checkbox" name="false">
<input type="checkbox" name="null">

控制結構

控制結構是程式碼區塊的延伸。 程式碼區塊的所有層面 (轉換成標記、內嵌 C#) 也適用於下列結構:

條件式 @if, else if, else, and @switch

@if 控制何時執行程式碼:

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

elseelse if 不需要 @ 符號:

@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 陳述式:

@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, and @do while

樣板化 HTML 可以透過迴圈控制陳述式轉譯。 若要轉譯人員清單:

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

支援的迴圈陳述式如下:

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

複合 @using

在 C# 中,using 陳述式可用來確保物件經過處置。 在 Razor 中,使用相同的機制來建立 HTML 協助程式,以包含其他內容。 在下列程式碼中,HTML 協助程式會使用 @using 陳述式來轉譯 <form> 標籤:

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

@try, catch, finally

例外狀況處理會類似於 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 陳述式來保護關鍵區段:

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

註解

Razor 支援 C# 和 HTML 註解:

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

程式碼會轉譯下列 HTML:

<!-- HTML comment -->

伺服器會先移除 Razor 註解,再轉譯網頁。 Razor 會使用 @* *@ 來分隔註解。 下列程式碼會標記為註解,以確保伺服器不會轉譯任何標記:

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

指示詞

Razor 指示詞是以隱含運算式表示,這些運算式具有保留關鍵字,後面接著 @ 符號。 指示詞通常會變更檢視的剖析方式或啟用不同的功能。

了解 Razor 如何針對檢視產生程式碼,可讓您更容易了解指示詞的運作方式。

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

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

程式碼會產生類似如下的類別:

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# 類別一節中說明如何檢視這個產生的類別。

@attribute

@attribute 指示詞會將指定屬性新增至所產生頁面或檢視的類別。 下列範例會新增 [Authorize] 屬性:

@attribute [Authorize]

@attribute 指示詞也可以用來在 Razor 元件中提供常數型路由範本。 在下列範例中,元件中的 @page 指示詞會取代為 @attribute 指示詞和 Constants.CounterRoute 中的常數型路由範本,這會在應用程式中的其他位置設定為 「/counter」:

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

@code

此案例僅適用於 Razor 元件 (.razor)。

@code 區塊會啟用 Razor 元件,來將 C# 成員 (欄位、屬性和方法) 新增至元件:

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

針對 Razor 元件,@code@functions 的別名,建議透過 @functions 使用。 允許一個以上的 @code 區塊。

@functions

@functions 指示詞能夠將 C# 成員 (欄位、屬性和方法) 新增至產生的類別:

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

Razor 元件中,透過 @functions 使用 @code 來新增 C# 成員。

例如:

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

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

程式碼會產生下列 HTML 標記:

<div>From method: Hello</div>

下列程式碼是產生的 Razor C# 類別:

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 方法會作為樣板化方法:

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

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

程式碼會轉譯下列 HTML:

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

@implements

@implements 指示詞會針對產生的類別實作介面。

下列範例會實作 System.IDisposable,如此便能呼叫 Dispose 方法:

@implements IDisposable

<h1>Example</h1>

@functions {
    private bool _isDisposed;

    ...

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

@inherits

@inherits 指示詞可讓您完全控制檢視所繼承的類別:

@inherits TypeNameOfClassToInheritFrom

下列程式碼是自訂 Razor Page 類型:

using Microsoft.AspNetCore.Mvc.Razor;

public abstract class CustomRazorPage<TModel> : RazorPage<TModel>
{
    public string CustomText { get; } = 
        "Gardyloo! - A Scottish warning yelled from a window before dumping" +
        "a slop bucket on the street below.";
}

CustomText 會顯示在檢視中:

@inherits CustomRazorPage<TModel>

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

程式碼會轉譯下列 HTML:

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

@model@inherits 可用於相同的檢視。 @inherits 可以在檢視匯入的 _ViewImports.cshtml 檔案中:

@inherits CustomRazorPage<TModel>

下列程式碼是強型別檢視的範例:

@inherits CustomRazorPage<TModel>

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

如果模型中傳遞了 "rick@contoso.com",檢視會產生下列 HTML 標記:

<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 從服務容器將服務插入至檢視。 如需詳細資訊,請參閱在檢視中插入相依性

@layout

此案例僅適用於 Razor 元件 (.razor)。

@layout 指示詞會針對具有 @page 指示詞的可路由 Razor 元件指定配置。 版面配置元件可用來避免程式碼重複和不一致。 如需詳細資訊,請參閱 ASP.NET Core Blazor 配置

@model

此案例僅適用於 MVC 檢視和 Razor Pages (.cshtml)。

@model 指示詞會指定傳遞至檢視或頁面的模型類型:

@model TypeNameOfModel

在使用個別使用者帳戶建立的 ASP.NET Core MVC 或 Razor Pages 應用程式中,Views/Account/Login.cshtml 會包含下列模型宣告:

@model LoginViewModel

產生的類別繼承自 RazorPage<LoginViewModel>

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Razor 會公開 Model 屬性,以存取傳遞至檢視的模型:

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

@model 指示詞會指定 Model 屬性的類型。 該指示詞會將 RazorPage<T> 中的 T 指定為檢視從中衍生的產生類別。 若未指定 @model 指示詞,Model 屬性的類型為 dynamic。 如需詳細資訊,請參閱Strongly typed models and the @model keyword

@namespace

@namespace 指示詞:

  • 設定所產生 Razor 頁面、MVC 檢視或 Razor 元件的類別命名空間。
  • 從目錄樹狀結構中最接近的匯入檔案、_ViewImports.cshtml (檢視或頁面) 或 _Imports.razor (Razor 元件),設定頁面、檢視或元件類別的根衍生命名空間。
@namespace Your.Namespace.Here

針對下表所示的 Razor Pages 範例:

  • 每個頁面都會匯入 Pages/_ViewImports.cshtml
  • Pages/_ViewImports.cshtml 包含 @namespace Hello.World
  • 每個頁面都有 Hello.World 作為其命名空間的根目錄。
Namespace
Pages/Index.cshtml Hello.World
Pages/MorePages/Page.cshtml Hello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtml Hello.World.MorePages.EvenMorePages

前述關聯性適用於匯入與 MVC 檢視和 Razor 元件搭配使用的檔案。

當多個匯入檔案具有 @namespace 指示詞時,會使用目錄樹狀結構中最接近頁面、檢視或元件的檔案來設定根命名空間。

如果上述範例中的 EvenMorePages 資料夾具備含 @namespace Another.Planet 的匯入檔案 (或者 Pages/MorePages/EvenMorePages/Page.cshtml 檔案包含 @namespace Another.Planet),則結果如下表所示。

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

@page

@page 指示詞會根據其出現的檔案類型而有不同的效果。 指示詞:

@preservewhitespace

此案例僅適用於 Razor 元件 (.razor)。

當設定為 false (預設值) 時,若出現下列情況,會從 Razor 元件 (.razor) 中移除所轉譯標記中的空格:

  • 在元素內前置或後置。
  • RenderFragment 參數中的前置或後置空格。 例如,傳遞至另一個元件的子內容。
  • 其在 C# 程式碼區塊之前或之後,例如 @if@foreach

@rendermode

此案例僅適用於 Razor 元件 (.razor)。

設定 Razor 元件的轉譯模式:

  • InteractiveServer:使用 Blazor Server 套用互動式伺服器轉譯。
  • InteractiveWebAssembly:使用 Blazor WebAssembly 套用互動式 WebAssembly 轉譯。
  • InteractiveAuto:一開始會使用 Blazor Server 套用互動式 WebAssembly 轉譯,然後在下載 Blazor 套件組合之後,會在後續造訪時使用 WebAssembly 套用互動式 WebAssembly 轉譯。

針對元件執行個體:

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

在元件定義中:

@rendermode InteractiveServer

注意

Blazor 範本在應用程式的 _Imports 檔案 (Components/_Imports.razor) 中包含 RenderMode 的靜態 using 指示詞,以取得較短的 @rendermode 語法:

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

如果沒有上述指示詞,元件必須以 @rendermode 語法明確指定靜態 RenderMode 類別:

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

如需詳細資訊,包括使用指示詞/指示詞屬性停用預先轉譯的指引,請參閱 ASP.NET Core Blazor 轉譯模式

@section

此案例僅適用於 MVC 檢視和 Razor Pages (.cshtml)。

@section 指示詞會與 MVC 和 Razor Razor 配置搭配使用,讓檢視或頁面可以轉譯 HTML 頁面不同部分中的內容。 如需詳細資訊,請參 ASP.NET 中的配置

@typeparam

此案例僅適用於 Razor 元件 (.razor)。

@typeparam 指示詞會宣告所產生元件類別的一般類型參數

@typeparam TEntity

支援具有 where 類型條件約束的泛型型別:

@typeparam TEntity where TEntity : IEntity

如需詳細資訊,請參閱下列文章:

@using

@using 指示詞會將 C# using 指示詞新增至產生的檢視:

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

RazorRazor 元件中,@using 也會控制哪些元件位於範圍內。

指示詞屬性

Razor 指示詞屬性是以隱含運算式表示,這些運算式具有保留關鍵字,後面接著 @ 符號。 指示詞屬性通常會變更元素的剖析方式或啟用不同的功能。

@attributes

此案例僅適用於 Razor 元件 (.razor)。

@attributes 允許元件轉譯非宣告的屬性。 如需詳細資訊,請參閱 ASP.NET Core Blazor 屬性展開和任意參數

@bind

此案例僅適用於 Razor 元件 (.razor)。

元件中的資料繫結會使用 @bind 屬性來完成。 如需詳細資訊,請參閱 ASP.NET Core Blazor 資料繫結

@bind:culture

此案例僅適用於 Razor 元件 (.razor)。

使用 @bind:culture 屬性搭配 @bind 屬性,來提供 System.Globalization.CultureInfo 以剖析和格式化一值。 如需詳細資訊,請參閱 ASP.NET Core Blazor 全球化和當地語系化

@formname

此案例僅適用於 Razor 元件 (.razor)。

@formname 會將表單名稱指派給 Razor 元件的純 HTML 表單或以 EditForm 為基礎的表單 (Editform 文件)。 @formname 的值應該是唯一的,可在下列情況下防止表單衝突:

  • 表單會放在具有多個表單的元件中。
  • 表單來自外部類別庫,通常是 NuGet 套件,適用於具有多個表單的元件,而應用程式作者不會控制程式庫的原始程式碼,以設定與元件中另一個表單所使用的名稱不同的外部表單名稱。

如需詳細資訊和範例,請參閱 ASP.NET Core Blazor 表單概觀

@on{EVENT}

此案例僅適用於 Razor 元件 (.razor)。

Razor 提供元件的事件處理功能。 如需詳細資訊,請參閱 ASP.NET Core Blazor 事件處理

@on{EVENT}:preventDefault

此案例僅適用於 Razor 元件 (.razor)。

防止事件的預設動作。

@on{EVENT}:stopPropagation

此案例僅適用於 Razor 元件 (.razor)。

停止事件的事件傳播。

@key

此案例僅適用於 Razor 元件 (.razor)。

@key 指示詞屬性導致元件差異比較演算法會根據索引鍵的值來保證元素或元件的保留。 如需詳細資訊,請參閱 在 ASP.NET Core Blazor 中保留元素、元件和模型關聯性

@ref

此案例僅適用於 Razor 元件 (.razor)。

元件參考 (@ref) 提供一種方式來參考元件執行個體,讓您可以對該執行個體發出命令。 如需詳細資訊,請參閱 ASP.NET Core Razor 元件

範本化的 Razor 委派

此案例僅適用於 MVC 檢視和 Razor Pages (.cshtml)。

Razor 範本可讓您使用下列格式定義 UI 程式碼片段:

@<tag>...</tag>

下列範例說明如何以 Func<T,TResult> 的形式指定範本化的 Razor 委派。 該範例會指定 dynamic 類型作為委派所封裝方法的參數。 並指定 object 類型作為委派的傳回值。 此範本會搭配具有 Name 屬性之 PetList<T> 來使用。

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 進行轉譯:

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

轉譯輸出:

<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 範本作為方法的引數。 在下列範例中,Repeat 方法會接收 Razor 範本。 此方法使用範本來產生 HTML 內容,並重複出現清單所提供的項目:

@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 方法並指定:

  • List<T>Pet
  • 每個寵物的重複次數。
  • 用於未排序清單中清單項目的內嵌範本。
<ul>
    @Repeat(pets, 3, @<li>@item.Name</li>)
</ul>

轉譯輸出:

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

標籤協助程式

此案例僅適用於 MVC 檢視和 Razor Pages (.cshtml)。

標籤協助程式有三個相關的指示詞。

指示詞 函式
@addTagHelper 使標籤協助程式可供檢視。
@removeTagHelper 移除先前從檢視新增的標籤協助程式。
@tagHelperPrefix 指定標籤前置字元,以啟用標籤協助程式支援,並將標籤協助程式使用方式設為明確。

Razor 保留關鍵字

Razor 關鍵字

  • page
  • namespace
  • functions
  • inherits
  • model
  • section
  • helper (ASP.NET Core 目前不支援)

Razor 關鍵字會使用 @(Razor Keyword) (例如 @(functions)) 逸出。

C# Razor 關鍵字

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

C# Razor 關鍵字必須使用 @(@C# Razor Keyword) (例如 @(@case)) 雙重逸出。 第一個 @ 會將 Razor 剖析器逸出。 第二個 @ 會將 C# 剖析器逸出。

Razor 未使用的保留關鍵字

  • class

檢查針對檢視所產生的 Razor C# 類別

RazorSDK 會處理 Razor 檔案的編譯。 根據預設,不會發出所產生的程式碼檔案。 若要啟用發出程式碼檔案,請將專案檔 (.csproj) 中的 EmitCompilerGeneratedFiles 指示詞設定為 true

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

Debug 組建組態中建置 6.0 專案 (net6.0) 時,Razor SDK 會在專案根目錄中產生 obj/Debug/net6.0/generated/ 目錄。 其子目錄包含發出的 Razor 頁面程式碼檔案。

RazorSDK 會處理 Razor 檔案的編譯。 建置專案時,Razor SDK 會在專案根目錄中產生 obj/{BUILD CONFIGURATION}/{TARGET FRAMEWORK MONIKER}/Razor 目錄。 Razor 目錄內的目錄結構會鏡像專案的目錄結構。

請考慮 ASP.NET Core Razor Pages 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 目錄:

 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

若要檢視針對 Pages/Index.cshtml 所產生的類別,請開啟 obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs

檢視查閱和區分大小寫

Razor 檢視引擎會針對檢視執行區分大小寫的查閱。 不過,實際查閱則取決於基礎檔案系統:

  • 檔案式來源:
    • 在具有不區分大小寫之檔案系統的作業系統上 (例如 Windows),實體檔案提供者查閱不會區分大小寫。 例如,return View("Test") 會產生 /Views/Home/Test.cshtml/Views/home/test.cshtml 和任何其他大小寫變體的相符項目。
    • 在區分大小寫的檔案系統上 (例如 Linux、OSX 及使用 EmbeddedFileProvider),查閱會區分大小寫。 例如,return View("Test") 特別符合 /Views/Home/Test.cshtml
  • 先行編譯的檢視:在 ASP.NET Core 2.0 和更新版本中,在所有作業系統上查閱先行編譯的檢視不會區分大小寫。 此行為與 Windows 上之實體檔案提供者的行為相同。 如果兩個先行編譯的檢視只有大小寫不同,查閱的結果不會由此決定。

建議開發人員比對檔案和目錄的大小寫以及下列項目的大小寫:

  • 區域、控制器和動作名稱。
  • Razor Pages.

比對大小寫可確保不論基礎檔案系統為何,部署作業都能夠找到其值。

Razor 所使用的匯入

下列匯入是由 ASP.NET Core Web 範本所產生,以支援 Razor 檔案:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;

其他資源

使用 Razor 語法進行 ASP.NET Web 程式設計的簡介提供了許多使用 Razor 語法進行程式設計的範例。