ASP.NET Core 中文文档 第四章 MVC(3.2)Razor 语法参考
2016-09-08 11:15
1106 查看
原文:Razor Syntax Reference
作者:Taylor Mullen、Rick Anderson
翻译:刘怡(AlexLEWIS)
校对:何镇汐
服务器最后渲染出的页面也是
HTML 如果需要包含
这样将渲染成下面的 HTML:
这样就不会因为在 HTML 特性或内容中包含邮件地址而误将
除 C# 关键字
任何在
隐式表达式通常不能包含空格,比如下面这段代码,上周的时间并不能通过减去当前时间来获得:
这将会被渲染为:
不过你可以使用显式表达式在表达式结果中把这段文本连接起来:
如果写成
将渲染为这段 HTML:
而浏览器将显示为:
HtmlHelper Raw 的输出不会被编码但会被渲染为 HTML 标记。
警告
为未经认可的用户输入使用
下面这段 Razor 标记:
将渲染为:
将渲染为:
当你需要渲染一段不包含 HTML 标签的 HTML 内容时可以试试这种办法。不过如果既不包含 HTML 标签也不包含 Razor 标签的话,你的 Razor 页面会在运行时出错。
以
为了将 HTML 内嵌到代码块中(以便能渲染出来),可以使用
如果上面代码不使用
当
你可以使用 switch 语句,就像这样:
你可以使用循环控制语句渲染出经过排版的 HTML,比如人名表:
你可以使用下面任意一种循环语句:
在 C# 中 using 语句用于确保对象被正确释放。在 Razor 中这一相同机制被用于创建包含额外内容的 HTML helpers 。比如我们可以利用 HTML helpers ,通过
你也可以在作用级别上执行一些类似上面这样的带 Tag Helpers 的操作。
异常处理和 C# 十分类似:
Razor 能通过 lock 语句保护重要代码:
被服务器渲染为:
Razor 注释将在页面渲染之前被服务器移除。Razor 使用
理解 Razor 如何为视图生成代码后,就能轻松理解指令是如何工作的。Razor 页面用于创建 C# 文件,比如这样一个 Razor 页面:
将生成一个类似下面这样的类:
查看生成视图的 Razor C# 类解释了如何查看这段自动生成的类。
比方说,如果你创建了一个带身份验证的 ASP.NET Core MVC 应用,你可以在 Views/Account/Login.cshtml Razor 视图文件中看到包含如下这段模型声明:
在 指令 样例类中,自动生成的类从
将生成下面这个类
Razor 页面将暴露一个
例如让我们来看下面这个自定义的 Razor 页面类型:
随后 Razor 将生成
你不能在同一个页面中同时使用
那么在下面这个强类型 Razor 文件
将生成这么一段 HTML 标记:
此时模型中被传入了「Rick@contoso.com」。
更多信息请查看 布局视图
例如:
生成如下 HTML 标记:
生成的 Razor C# 类似下面这段:
@addTagHelper
@removeTagHelper
@tagHelperPrefix
inherits
model
section
helper (ASP.NET Core 不支持)
Razor 关键字可以转义,形如
do
default
for
foreach
if
lock
switch
try
using
while
C# Razor 关键字需要使用两个转义符号,形如
class
下列是所有 Razor 保留字的转义:
通过为 MVC 加上上面这个类来覆盖 ICompilationService :
在
返回目录
作者:Taylor Mullen、Rick 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:Support@contoso.com">Support@contoso.com</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>Age@(joe.Age)</p>
如果写成
<p>Age@joe.Age</p>这种非显式表达式,那么它将当做邮件地址来处理并渲染为
<p>Age@joe.Age</p>。当写成显式表达式时,将渲染为
<p>Age33</p>。
Expression 编码
C# 表达式计算后的字符串是 HTML 编码的。C# 表达式的计算结果为 IHtmlContent,将直接通过IHtmlContent.WriteTo渲染到页面。不会计算为
IHtmlContent的 C# 表达式将会转换为字符串(通过
ToString)并在渲染前编码。比方说下面这段 Razor 标记:
@("<span>Hello World</span>")
将渲染为这段 HTML:
<span>Hello World</span>
而浏览器将显示为:
<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#)都适用以下结构:@if
、else if
、else
与 @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 的操作。
@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 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: Rick@contoso.com</div> <div>Custom text: Hello World</div>
此时模型中被传入了「Rick@contoso.com」。
更多信息请查看 布局视图
@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 指令的详细信息可以点击链接查看。@addTagHelper
@removeTagHelper
@tagHelperPrefix
Razor 保留关键字
Razor 关键字
functionsinherits
model
section
helper (ASP.NET Core 不支持)
Razor 关键字可以转义,形如
@(Razor Keyword),举一个例子:
@(functions)。上面是完整举例。
C# Razor 关键字
casedo
default
for
foreach
if
lock
switch
try
using
while
C# Razor 关键字需要使用两个转义符号,形如
@(@C# Razor Keyword),举一个实际例子:
@(@case)。第一个
@转义符用于 Razor 解析,第二个
@转义符用于 C# 解析。上面是完整举例。
Razor 未使用的保留关键字
namespaceclass
下列是所有 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上设断点。
返回目录
相关文章推荐
- ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入
- ASP.NET Core 中文文档 第四章 MVC(2.3)格式化响应数据
- ASP.NET Core 中文文档 第四章 MVC(3.6.2 )自定义标签辅助类(Tag Helpers)
- ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由
- ASP.NET Core 中文文档 第四章 MVC(4.1)Controllers, Actions 和 Action Results
- ASP.NET Core 中文文档 第四章 MVC(4.5)测试控制器逻辑
- ASP.NET Core 中文文档 第四章 MVC(3.4)如何使用表单
- ASP.NET Core 中文文档 第四章 MVC(2.1)模型绑定
- ASP.NET Core 中文文档 第四章 MVC(3.7 )局部视图(partial)
- ASP.NET Core 中文文档 第四章 MVC(3.9)视图组件
- ASP.NET Core 中文文档 第四章 MVC(3.1)视图概述
- ASP.NET Core 中文文档 第四章 MVC(3.3)布局视图
- ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器
- ASP.NET Core 中文文档 第四章 MVC(2.2)模型验证
- ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览
- [转]ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器
- ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器
- ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍
- ASP.NET Core 中文文档 第四章 MVC(4.6)Areas(区域)
- ASP.NET MVC 3 Razor 多国语言参考解决方案 补充