2021-05-12 14:32:11
ASP.NET Core 5.0 MVC中的 Razor 頁面 介紹
Razor 是一個用於將基於伺服器的程式碼嵌入到網頁中的標記語法。 Razor語法由 Razor 標記、c # 和 HTML 組成。 通常包含 Razor 的檔案的擴充套件名 cshtml
Razor 語法
Razor 支援 c #,並使用 @
符號從 HTML 轉換為 c #。 Razor 計算 c # 表示式並在 HTML 輸出中呈現。
當 @
符號後跟
該程式碼在 HTML 中使用單個 @
符號呈現:
<p>@Username</p>
包含電子郵件地址的 HTML 屬性和內容不將 @
符號視為轉換字元。 以下範例中的電子郵件地址將通過分析來保持不變 Razor :
<a href="mailto:Support@contoso.com">Support@contoso.com</a>
若要對 @
標記中的符號進行跳脫 Razor ,請使用第二個 @
符號:
<p>@@Username</p>
隱式 Razor 表示式
隱式 Razor 表示式以開頭, @
後跟 c # 程式碼:
隱式表示式不能包含空格,但 C# await
關鍵字除外。 如果該 C# 語句具有明確的結束標記,則可以混用空格:
<p>@await DoSomething("hello", "world")</p>
隱式表示式 不能 包含 C# 泛型,因為括號 (<>
) 內的字元會被解釋為 HTML 標記。 以下程式碼 無 效:
<p>@GenericMethod<int>()</p>
上述程式碼生成與以下錯誤之一類似的編譯器錯誤:
-
"int" 元素未結束。 所有元素都必須自結束或具有匹配的結束標記。
-
無法將方法組 "GenericMethod" 轉換為非委託型別 "object"。 是否希望呼叫此方法?`
泛型方法呼叫必須在
顯式 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:
<span>Hello World</span>
HTML 在瀏覽器中顯示為純文字:
<跨越 > Hello World < /span>
HtmlHelper.Raw
輸出不進行編碼,但呈現為 HTML 標記。
警告
對未經審查的使用者輸入使用
HtmlHelper.Raw
會帶來安全風險。 使用者輸入可能包含惡意的 JavaScript 或其他攻擊。 審查使用者輸入比較困難。 應避免對使用者輸入使用@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 頁面可轉換回 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>
標記之間的內容。 -
<text>
標記之前或之後的空格不會顯示在 HTML 輸出中。
顯式行轉換
要在程式碼塊內以 HTML 形式呈現整個行的其餘內容,請使用 @:
語法:
@for (var i = 0; i < people.Length; i++) { var person = people[i]; @:Name: @person.Name }
如果 @:
程式碼中沒有,則 Razor 會生成執行時錯誤。
@
檔案中的額外字元 Razor 可能會導致在塊中後面的語句中出現編譯器錯誤。 這些編譯器錯誤可能難以理解,因為實際錯誤發生在報告的錯誤之前。 將多個隱式/顯式表示式合併到單個程式碼塊以後,經常會發生此錯誤。
控制結構
控制結構是對程式碼塊的擴充套件。 程式碼塊的各個方面(轉換為標記、內聯 C#)同樣適用於以下結構:
條件語句 @if, else if, else, and @switch
@if
控制何時執行程式碼:
@if (value % 2 == 0) { <p>The value was even.</p> }
else
和else 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 指令由帶有符號後的保留關鍵字的隱式表示式表示 @
。 指令通常用於更改檢視分析方式或啟用不同的功能。
@attribute
@attribute
指令將給定的屬性新增到生成的頁或檢視的類中。 以下範例新增 [Authorize]
屬性:
@attribute [Authorize]
@code
此方案僅適用於 Razor ( razor) 的元件。
@code
塊使
@code { // C# members (fields, properties, and methods) }
對於 Razor 元件, @code
是的別名,
@functions
@functions
指令允許將 C# 成員(欄位、屬性和方法)新增到生成的類中:
@functions { // C# members (fields, properties, and methods) }
在
例如:
@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("rn<div>From method: "); Write(GetHello()); WriteLiteral("</div>rn"); } #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
指令為生成的類實現介面。
以下範例實現
@implements IDisposable <h1>Example</h1> @functions { private bool _isDisposed; ... public void Dispose() => _isDisposed = true; }
@inherits
@inherits
指令對檢視繼承的類提供完全控制:
@inherits TypeNameOfClassToInheritFrom
下面的程式碼是一個自定義的 Razor 頁型別:
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 頁面可以將服務從
@layout
此方案僅適用於 Razor ( razor) 的元件。
@layout
指令指定 Razor 具有指令的可路由元件的佈局
@model
此方案僅適用於 Razor () 的 MVC 檢視和頁面。
@model
指令指定傳遞到檢視或頁面的模型型別:
@model TypeNameOfModel
在 Razor 使用單獨的使用者帳戶建立的 ASP.NET CORE MVC 或頁面應用中, Views/Account/Login。 cshtml 包含以下模型宣告:
@model LoginViewModel
生成的類繼承自 RazorPage<dynamic>
:
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
。 有關詳細資訊,請參閱
@namespace
@namespace
指令:
-
設定生成的 Razor 頁、MVC 檢視或元件的類的名稱空間 Razor 。
-
在目錄樹中最近的匯入檔案中設定頁面、檢視或元件類的根派生名稱空間, _ViewImports) 或 _Imports razor (元件) (檢視或頁面。 Razor
@namespace Your.Namespace.Here
對於 Razor 下表中所示的頁面範例:
-
每個頁面都匯入 Pages/_ViewImports.cshtml。
-
Pages/_ViewImports.cshtml 包含
@namespace Hello.World
。 -
每個頁面都有
Hello.World
,作為其名稱空間的根。
頁 | 名稱空間 |
---|---|
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
),則結果如下表所示。
頁 | 名稱空間 |
---|---|
Pages/Index. cshtml | Hello.World |
Pages/MorePages/Page.cshtml | Hello.World.MorePages |
Pages/MorePages/EvenMorePages/Page.cshtml | Another.Planet |
@page
@page
指令具有不同的效果,具體取決於其所在檔案的型別。 指令:
-
在 cshtml 檔案中,指示該檔案是一個 Razor 頁面。 有關詳細資訊,請參閱
-
指定 Razor 元件應直接處理請求。 有關詳細資訊,請參閱
@preservewhitespace
此方案僅適用於 Razor (.razor
) 的元件。
如果設定為 false
(預設) ,則將在 Razor 以下情況下刪除從元件 () 中呈現的標記中的空白 .razor
:
-
元素中的前導或尾隨空白。
-
RenderFragment
引數中的前導或尾隨空白。 例如,傳遞到另一個元件的子內容。 -
在 C# 程式碼塊(例如
@if
和@foreach
)之前或之後。
@section
此方案僅適用於 Razor () 的 MVC 檢視和頁面。
@section
指令與
@using
@using
指令用於向生成的檢視新增 C# using
指令:
@using System.IO @{ var dir = Directory.GetCurrentDirectory(); } <p>@dir</p>
在 "
指令屬性
Razor 指令特性由帶有符號後的保留關鍵字的隱式表示式表示 @
。 指令特性通常會改變元素的分析方式,或實現不同的功能。
@attributes
此方案僅適用於 Razor ( razor) 的元件。
@attributes
允許元件呈現未宣告的屬性。 有關詳細資訊,請參閱
@bind
此方案僅適用於 Razor ( razor) 的元件。
元件中的資料繫結通過 @bind
屬性實現。 有關詳細資訊,請參閱
@on{EVENT}
此方案僅適用於 Razor ( razor) 的元件。
Razor 為元件提供事件處理功能。 有關詳細資訊,請參閱
@on{EVENT}:preventDefault
此方案僅適用於 Razor ( razor) 的元件。
禁止事件的預設操作。
@on{EVENT}:stopPropagation
此方案僅適用於 Razor ( razor) 的元件。
停止事件的事件傳播。
@key
此方案僅適用於 Razor ( razor) 的元件。
@key
指令屬性使元件比較演演算法保證基於鍵的值保留元素或元件。 有關詳細資訊,請參閱
@ref
此方案僅適用於 Razor ( razor) 的元件。
元件參照 (@ref
) 提供了一種參照元件範例的方法,以便可以向該範例發出命令。 有關詳細資訊,請參閱
@typeparam
此方案僅適用於 Razor ( razor) 的元件。
@typeparam
指令宣告生成的元件類的泛型型別引數。 有關詳細資訊,請參閱
模板化 Razor 委託
Razor 模板允許使用以下格式定義 UI 程式碼段:
@<tag>...</tag>
下面的範例演示如何將模板化 Razor 委託指定為
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; } }
使用前面範例中的 pets 列表,呼叫 Repeat
方法以及:
-
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>
標記幫助程式
此方案僅適用於 Razor () 的 MVC 檢視和頁面。
指令 | 函數 |
---|---|
向檢視提供標記幫助程式。 | |
從檢視中刪除以前新增的標記幫助程式。 | |
-------------------------------------------------------
相關文章