Razor 语法

Razor 语法

原文:Razor Syntax Reference
作者:Taylor MullenRick Anderson
翻译:刘怡(AlexLEWIS)
校对:何镇汐

什么是 Razor?

Razor 是一种基于服务器端代码的可以转换为网页的标记语法。Razor 语法包括 Razor 标记、C# 和 HTML 组成。包含 Razor 的文件通常后缀名为 .cshtml 。

渲染 HTML

Razor 的默认语言是 HTML。从 Razor 渲染为 HTML 和直接一个 HTML 文件没啥区别,这种 Razor 文件包含下面的标记:

复制代码

<p>Hello World</p>

服务器最后渲染出的页面也是 <p>Hello World</p>,没有任何改变。

Razor 语法

Razor 支持 C# 并通过使用 @ 符号从 HTML 切换到 C#。Razor 运算 C# 表达式并将之渲染为 HTML 输出。Razor 能通过 Razor 指定的标记从 HTML 切换到 C#。当 @ 符号后面紧跟一个 Razor 保留字 ,则将切换为 Razor 特定标记,不然的话切换到普通的 C#。

HTML 如果需要包含 @ 符号的话需要使用两个 @@ 符号来进行转义,比如:

复制代码

<p>@@Username</p>

这样将渲染成下面的 HTML:

复制代码

 <p>@Username</p>

这样就不会因为在 HTML 特性或内容中包含邮件地址而误将 @ 处理为转换字符(进而切换到 Razor 指定标记或 C# 模式)。
<a href="mailto:[email protected]">[email protected]</a>

隐式 Razor 表达式

隐式 Razor 表达式起于 @ 符号,后面紧跟 C# 代码,比如:

复制代码

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

除 C# 关键字 await 以外的隐式表达式都不能包含空格。比如你可以在 C# 语句中混进一些空格,只要 C# 语句的结尾明确:

复制代码

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

显式 Razor 表达式

显式 Razor 表达式包含一个带一对括号的 @ 符号,比如在页面上渲染上周的时间:

复制代码

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

任何在 @() 内的内容都会被运算并渲染输出。
隐式表达式通常不能包含空格,比如下面这段代码,上周的时间并不能通过减去当前时间来获得:

复制代码

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

这将会被渲染为:

复制代码

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

不过你可以使用显式表达式在表达式结果中把这段文本连接起来:

复制代码

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

<p>[email protected](joe.Age)</p>

如果写成 <p>[email protected]</p> 这种非显式表达式,那么它将当做邮件地址来处理并渲染为 <p>[email protected]</p>。当写成显式表达式时,将渲染为 <p>Age33</p> 。

Expression 编码

C# 表达式计算后的字符串是 HTML 编码的。C# 表达式的计算结果为 IHtmlContent,将直接通过 IHtmlContent.WriteTo 渲染到页面。不会计算为 IHtmlContent 的 C# 表达式将会转换为字符串(通过 ToString)并在渲染前编码。比方说下面这段 Razor 标记:

复制代码

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

将渲染为这段 HTML:

复制代码

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

而浏览器将显示为:

<span>Hello World</span>

HtmlHelper Raw 的输出不会被编码但会被渲染为 HTML 标记。

警告
为未经认可的用户输入使用 HtmlHelper.Raw 是存在安全风险的。用户输入可能会包含恶意的 JavaScript 代码或其他攻击。为用户输入的信息进行过滤和清理是非常困难的,所以尽量避免为用户输入使用 HtmlHelper.Raw

下面这段 Razor 标记:

复制代码

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

将渲染为:

复制代码

<span>Hello World</span>

Razor 代码块

Razor 代码块起于 @ 并用 {} 包围起来。不像表达式,代码块内的 C# 代码不会被渲染到页面中。Razor 页面中的代码块和表达式将共享同一个作用域,并按顺序定义(也就是说,之前在代码块中声明的对象可以在之后的代码块与表达式中使用)。

复制代码

@{
    var output = "Hello World";
}

<p>The rendered result: @output</p>

将渲染为:

复制代码

<p>The rendered result: Hello World</p>

隐式转换

代码块的默认语言是 C#,但你可以随时切换到 HTML。代码块内的 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 页面会在运行时出错。

以 @: 符号显式行转换

为了将 HTML 内嵌到代码块中(以便能渲染出来),可以使用 @: 语法:

复制代码

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

如果上面代码不使用 @: ,你的 Razor 页面会在运行时出错。

控制结构

控制结构(controller structures)是代码块表达式。所有类型的代码块(包括过渡标记、内联式C#)都适用以下结构:

@ifelse ifelse 与 @switch 条件

当 @if 满足指定条件时,@if 系列关键词将获得控制权并运行 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 was not large and is odd.</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 was not 1 or 1337.</p>
        break;
}

@for@foreach@while 与 @do while 循环

你可以使用循环控制语句渲染出经过排版的 HTML,比如人名表:

复制代码

@{
    var people = new Person[]
    {
          new Person("John", 33),
          new Person("Doe", 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 helpers 。比如我们可以利用 HTML helpers ,通过 @using 语句渲染 form 标签:

复制代码

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

你也可以在作用级别上执行一些类似上面这样的带 Tag Helpers 的操作。

@trycatch 与 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 comment -->

Razor 注释将在页面渲染之前被服务器移除。Razor 使用 @* *@ 来界定注释。下面这段代码就被注释掉了,因此服务器不会渲染出任何标记:

复制代码

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

指令

Razor 指令表现为「@ 符号 + 保留关键字」的隐式表达式。指令通常能改变页面的解析或为 Razor 页面启用不同的功能。
理解 Razor 如何为视图生成代码后,就能轻松理解指令是如何工作的。Razor 页面用于创建 C# 文件,比如这样一个 Razor 页面:

复制代码

@{
    var output = "Hello World";
}

<div>Output: @output</div>

将生成一个类似下面这样的类:

复制代码

public class _Views_Something_cshtml : RazorPage<dynamic>
{
    public override async Task ExecuteAsync()
    {
        var output = "Hello World";

        WriteLiteral("/r/n<div>Output: ");
        Write(output);
        WriteLiteral("</div>");
    }
}

查看生成视图的 Razor C# 类解释了如何查看这段自动生成的类。

@using

@using 指令将为 razor 页面增加 C# 的 using 指令。

复制代码

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

@model

@model 指令让你可以为传入 Razor 页面的模型指定类型,其语法为:

复制代码

@model TypeNameOfModel

比方说,如果你创建了一个带身份验证的 ASP.NET Core MVC 应用,你可以在Views/Account/Login.cshtml Razor 视图文件中看到包含如下这段模型声明:

复制代码

@model LoginViewModel

在 指令 样例类中,自动生成的类从 RazorPage<dynamic> 继承。通过添加 @model,你可以控制继承什么,比如:

复制代码

@model LoginViewModel

将生成下面这个类

复制代码

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Razor 页面将暴露一个 Model 属性给传入页面的模型访问。

复制代码

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

@model 指令能为这个属性指定类型(通过为自动生成的类 RazorPage<T> 中的 T 指定类型)。如果你没有指定 @model 指令,那么 Model 属性将使用类型 dynamic 。模型的值将从控制器传入视图。更多请查阅 Strongly typed models and the @model keyword 。

@inherits

@inherits 指令让你具有 Razor 页面所继承类的完整控制权:

复制代码

@inherits TypeNameOfClassToInheritFrom

例如让我们来看下面这个自定义的 Razor 页面类型:

复制代码

using Microsoft.AspNetCore.Mvc.Razor;

public abstract class CustomRazorPage<TModel> : RazorPage<TModel>
{
    public string CustomText { get; } = "Hello World.";
}

随后 Razor 将生成 <div>Custom text: Hello World</div> 。

复制代码

@inherits CustomRazorPage<TModel>

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

你不能在同一个页面中同时使用 @model 和 @inherits。你可以在 *_ViewImports.cshtml* 文件中使用@inherits 指令,然后在其他 Razor 页面中导入。举例来说,如果你的 Razor 视图导入了下面这个 *_ViewImports.cshtml* 文件:

复制代码

@inherits CustomRazorPage<TModel>

那么在下面这个强类型 Razor 文件

复制代码

@inherits CustomRazorPage<TModel>

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

将生成这么一段 HTML 标记:

复制代码

<div>The Login Email: [email protected]</div>
<div>Custom text: Hello World</div>

此时模型中被传入了「[email protected]」。

更多信息请查看 布局视图

@inject

@inject 指令可让你在 Razor 页面中从 服务容器 注入服务,更多请查看 See Injecting Services Into Views 。

@functions

@functions 指令让你能在 Razor 页面中添加函数级别的内容,其语法为:

复制代码

@functions { // C# Code }

例如:

复制代码

@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

@section

@section 指令通常与 布局页 一起使用,这样可以使视图所渲染的 HTML 页面能具有不同的内容。更多请查看 Sections 。

TagHelpers

下列 Tag Helpers 指令的详细信息可以点击链接查看。

Razor 保留关键字

Razor 关键字

  • functions
  • inherits
  • model
  • section
  • helper (ASP.NET Core 不支持)

Razor 关键字可以转义,形如 @(Razor Keyword) ,举一个例子:@(functions) 。上面是完整举例。

C# Razor 关键字

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

C# Razor 关键字需要使用两个转义符号,形如 @(@C# Razor Keyword),举一个实际例子:@(@case)。第一个 @ 转义符用于 Razor 解析,第二个 @ 转义符用于 C# 解析。上面是完整举例。

Razor 未使用的保留关键字

  • namespace
  • class

下列是所有 Razor 保留字的转义:

复制代码

@{
    // Razor keywords.

    var @functions = "functions";
    var @inherits = "inherits";
    var @model = "model";
    var @section = "section";
    var @helper = "helper";         // Not supported by ASP.NET Core.

    // C# Razor keywords.

    var @case = "case";
    var @do = "do";
    var @default = "default";
    var @for = "for";
    var @foreach = "foreach";
    var @if = "if";
    var @lock = "lock";
    var @switch = "switch";
    var @try = "try";
    var @using = "using";
    var @while = "while";

    // Reserved keywords not used.

    var @namespace = "namespace";
    var @class = "class";
}

<p>Razor keywords.</p>
<div>@(functions)</div>
<div>@(inherits)</div>
<div>@(model)</div>
<div>@(section)</div>
<div>@(helper)</div>

<p>C# Razor keywords.</p>
<div>@(@case)</div>
<div>@(@do)</div>
<div>@(@default)</div>
<div>@(@for)</div>
<div>@(@foreach)</div>
<div>@(@if)</div>
<div>@(@lock)</div>
<div>@(@switch)</div>
<div>@(@try)</div>
<div>@(@using)</div>
<div>@(@while)</div>

<p>Reserved keywords not used</p>
<div>@(@namespace)</div>
<div>@(@class)</div>

查看生成视图的 Razor C# 类

在 ASP.NET Core MVC 项目中增加下面这个类:

复制代码

using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

public class CustomCompilationService : DefaultRoslynCompilationService, ICompilationService
{
    public CustomCompilationService(ApplicationPartManager partManager,
        IOptions<RazorViewEngineOptions> optionsAccessor,
        IRazorViewEngineFileProviderAccessor fileProviderAccessor,
        ILoggerFactory loggerFactory)
        : base(partManager, optionsAccessor, fileProviderAccessor, loggerFactory)
    {
    }

    CompilationResult ICompilationService.Compile(RelativeFileInfo fileInfo,
        string compilationContent)
    {
        return base.Compile(fileInfo, compilationContent);
    }
}

通过为 MVC 加上上面这个类来覆盖 ICompilationService :

复制代码

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSingleton<ICompilationService, CustomCompilationService>();
}

在 Compile 方法的 CustomCompilationService 上、在视图compilationContent 上设断点。

返回目录

时间: 2024-10-14 14:02:44

Razor 语法的相关文章

【转载】【MVC 学习 Razor语法】

Razor是MVC3中才有的新的视图引擎.我们知道,在ASP.NET中,ASPX的视图引擎依靠<%和%>来调用C#指令.而MVC3以后有了一套新的使用@标记的Razor语法,使用起来更灵活更简洁.下面通过一些简单示例让大家快速撑握Razor语法的使用. 准备工作 在演示Razor语法的使用之前,我们需要做一些准备工作. 1.打开VS创建一个ASP.NET MVC空项目,很简单,就不具体演示了. 2.添加一个Model.在项目的Models文件夹中添加一个名为Product的类.在这我们把前一篇

Asp.net MVC]Asp.net MVC5系列——Razor语法

目录 概念 Razor语法 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列--第一个项目 [Asp.net MVC]Asp.net MVC5系列--添加视图 [Asp.net MVC]Asp.net MVC5系列--添加模型 [Asp.net MVC]Asp.net MVC5系列--从控制器访问模型中的数据 [Asp.net MVC]Asp.net MVC5系列--添加数据 [Asp.net MVC]Asp.net MVC5系列--在模型中添加验证规则 [Asp.net

MVC3/4/5/6 布局页及Razor语法

一.目录结构 二.Razor语法 代码块:@{},如:@{Html.Raw(“”);} @if(){} @switch(){} @for(){} @foreach(){} @while(){} @do{}while(){} 代码块内语句以分号结束 表达式或变量:以@开始,如:@User.Name或@(User.Name + “欢迎你”),@() 变量可以通过var来声明,且只能在代码块中,如:@{var abc=”aaa”;} 方法调用:以@开始,如:@Html.Encode(“”) 单行文本输

Razor语法

Razor并不是新的开发语言,它只是一种用在View页面代码区块的编写风格,所用的代码一样都是c#,因此开发人员不需要额外学习新的语言. Razor基本语法 1.在view页面输出表达式或者单个变量,只要在c#语句前面加上 @ 符号,同时在c#语句前后加上括号.razor表达式或者单个变量是不需要分号结尾的.范例如下: 表达式:@(ViewBag.Name+ViewBag.Level) 单个变量:@(DateTime.Now) 或者@DateTime.Now  (单个变量可以不加括号,建议加上)

Asp.net MVC3 Razor语法小记

Asp.net MVC3 Razor语法小记 1.在MVC View中使用 三元运算符的方式:@(bool?"":"") 2.在@{}中输出一行:@:<html>.如果这一行的上下文在程序代码中则用:@Html.Raw(string.Format(""));而不是Html.Raw(); 3.Radio默认选中: @Html.RadioButtonFor(m => m.BookType, 0, new { @checked=&qu

ASP.NET MVC中的Razor语法

1.Razor的基本语法 @* 多行代码时需要包含在大括号内{}和每句代码后都需要加分号; *@ @{ ViewBag.Title = "Index"; ViewBag.Name = "Linq"; ViewBag.IsOk = false; List<string> list = new List<string>() { "11", "22", "33", "44&quo

C# 的主要 Razor 语法规则

Razor 代码封装于 @{ ... } 中 行内表达式(变量和函数)以 @ 开头 代码语句以分号结尾 字符串由引号包围 C# 代码对大小写敏感 C# 文件的扩展名是 .cshtml 如何工作? Razor 是一种简单的编程语法,用于在网页中嵌入服务器端代码. Razor 语法基于 ASP.NET 框架,该框架是微软的 .NET 框架特别为 web 应用程序开发而设计的组成部分. Razor 语法赋予您所有 ASP.NET 的能力,但是使用了简化过的语法,如果您是初学者,则更容易学习,如果您是专

mvc 4 razor语法

mvc 4 razor语法讲解和使用 1.这里的  @{Layout="文件路径";}  代码块指定了整个项目默认所使用的布局文件(如图:) @RenderBody()对于所有的页面默认的情况下都会使用这个布局(WebForm的模板) @RenderBody()相当于一个占位符其他页面的所有内容都会被引擎渲染在这个地方. @RenderSecion()这个占位符表示:在这里会渲染页面里面的一个节(可以是html代码也可以是c#代码和Html的结合体). @RenderSection(&

mvc 4 razor语法讲解和使用

Razor语法的分类 @using : 引入命名空间 @model :声明强类型的数据model类型 @section :定义要实现母版页的节的信息 @RenderBody():当创建基于页面的布局时,视图的内容会和布局页合并,而新创建的视图的内容会通过布局页面的@RenderBody方法呈现在标签之间. @RenderPage :呈现一个页面.比如网页中固定的头部可以单独放在一个共享视图文件中,然后在布局也免中通过这个方法调用,例如 @RenderPage("~/Views/Shared/_H