ASP.NET Core 5.0 MVC中的 Razor 頁面 介紹

 

Razor 是一個用於將基於服務器的代碼嵌入到網頁中的標記語法。 Razor語法由 Razor 標記、c # 和 HTML 組成。 一般包含 Razor 的文件的擴展名 cshtmlhtml

Razor 語法

Razor 支持 c #,並使用 @ 符號從 HTML 轉換爲 c #。 Razor 計算 c # 表達式並在 HTML 輸出中呈現。算法

@ 符號後跟 Razor 保留關鍵字時,它會轉換爲 Razor 特定標記。 不然會轉換爲純 C#。express

該代碼在 HTML 中使用單個 @ 符號呈現: api

<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# 語句具備明確的結束標記,則能夠混用空格:mvc

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

隱式表達式 不能 包含 C# 泛型,由於括號 (<>) 內的字符會被解釋爲 HTML 標記。 如下代碼 效:app

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

上述代碼生成與如下錯誤之一相似的編譯器錯誤:async

  • "int" 元素未結束。 全部元素都必須自結束或具備匹配的結束標記。

  • 沒法將方法組 "GenericMethod" 轉換爲非委託類型 "object"。 是否但願調用此方法?`

泛型方法調用必須在顯式 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 在瀏覽器中顯示爲純文本:

<跨越 > 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 頁面可轉換回 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>
}
 不須要  符號: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 指令由帶有符號後的保留關鍵字的隱式表達式表示 @ 。 指令一般用於更改視圖分析方式或啓用不一樣的功能。

@attribute

@attribute 指令將給定的屬性添加到生成的頁或視圖的類中。 如下示例添加 [Authorize] 屬性:

@attribute [Authorize]

@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 組件中,使用 @code Over @functions 來添加 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 頁類型:

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>
 可在同一視圖中使用。  可位於視圖導入的 _ViewImports.cshtml 文件中:@model@inherits@inherits
@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 具備指令的可路由組件的佈局 @page 。 佈局組件用於避免代碼重複和不一致。 有關詳細信息,請參閱 ASP.NET Core Blazor 佈局

@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。 有關詳細信息,請參閱強類型模型和 @model 關鍵字

@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 指令具備不一樣的效果,具體取決於其所在文件的類型。 指令:

@preservewhitespace

此方案僅適用於 Razor (.razor) 的組件。

若是設置爲 false (默認) ,則將在 Razor 如下狀況下刪除從組件 () 中呈現的標記中的空白 .razor

  • 元素中的前導或尾隨空白。

  • RenderFragment 參數中的前導或尾隨空白。 例如,傳遞到另外一個組件的子內容。

  • 在 C# 代碼塊(例如 @if@foreach)以前或以後。

@section

此方案僅適用於 Razor () 的 MVC 視圖和頁面。

@section指令與MVC 和 Razor 頁面佈局結合使用,以使視圖或頁面可以在 HTML 頁面的不一樣部分中呈現內容。 有關詳細信息,請參閱 ASP.NET Core 中的佈局

@using

@using 指令用於向生成的視圖添加 C# using 指令:

@using System.IO
@{
    var dir = Directory.GetCurrentDirectory();
}
<p>@dir</p>
在 " Razor 組件" 中,  還控制哪些組件在範圍內。@using

指令屬性

Razor 指令特性由帶有符號後的保留關鍵字的隱式表達式表示 @ 。 指令特性一般會改變元素的分析方式,或實現不一樣的功能。

@attributes

此方案僅適用於 Razor ( razor) 的組件。

@attributes 容許組件呈現未聲明的屬性。 有關詳細信息,請參閱 建立和使用 ASP.NET Core Razor 組件

@bind

此方案僅適用於 Razor ( razor) 的組件。

組件中的數據綁定經過 @bind 屬性實現。 有關詳細信息,請參閱 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 Razor 組件

@ref

此方案僅適用於 Razor ( razor) 的組件。

組件引用 (@ref) 提供了一種引用組件實例的方法,以即可以向該實例發出命令。 有關詳細信息,請參閱 建立和使用 ASP.NET Core Razor 組件

@typeparam

此方案僅適用於 Razor ( razor) 的組件。

@typeparam 指令聲明生成的組件類的泛型類型參數。 有關詳細信息,請參閱 ASP.NET Core Blazor 模板化組件

模板化 Razor 委託

Razor 模板容許使用如下格式定義 UI 代碼段:

 @<tag>...</tag>

下面的示例演示如何將模板化 Razor 委託指定爲 Func 。 爲委託封裝的方法的參數指定動態類型。 將對象類型指定爲委託的返回值。 該模板與 Pet(具備 Name 屬性)的 List 一塊兒使用。

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" }
    };
}
使用  語句提供的  呈現該模板: foreachpets
@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 方法以及:

  • PetList

  • 每隻寵物的重複次數。

  • 用於無序列表的列表項的內聯模板。 

<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 視圖和頁面。

標記幫助程序有三個相關指令。

指令 函數
@addTagHelper 向視圖提供標記幫助程序。
@removeTagHelper 從視圖中刪除之前添加的標記幫助程序。
@tagHelperPrefix 指定標記前綴,以啓用標記幫助程序支持並闡明標記幫助程序的用法。

-------------------------------------------------------

相關文章
相關標籤/搜索