Razor页面
一个Razor内容页实际上是一个用于生成HTML页面的模板。典型的Razor页面可以包含:静态HTML标签、Tag Helpers(用于动态生成HTML的帮助类)以及C#代码。其中的C#代码是内嵌在静态HTML代码中的,而Tag Helpers
是一系列规则或者语法的帮助类。
如何渲染HTML ?
Razor默认的语言即是HTML。在Razor引擎中渲染HTML标记与在静态的HTML文件中渲染HTML是相同的,在服务器端编译时不会对.cshtml
文件中的HTML标记作任何更改,会按HTML标记原样输出到客户端浏览器。
Razor语法
在Razor引擎中,所有的代码块都必须使用形如 @{ ... }
包裹起来,当单词以 @
标记开始时,Razor引擎会认为其后的代码为C#代码。
参考如下的Razor代码块:
@{
var i=0;
}
使用以上定义的变量i
:
i = @i
输出结果:
i = 0
如果只需要输出简单的变量,则可以直接使用@
符号,后面接变量,不使用代码块{}
包裹,如下:
My name is @UserName
这里的
@UserName
即为一个Razor变量,由于没有其他复杂的声明或者逻辑处理,我们可以不使用代码块。
这时,可能有童鞋会有问题了:“如果我想将@
符号作为输出字符,而不是Razor语法标记,应该怎么作呢?”。能发现这个问题的童鞋,是很善于学习和发现的。在实现运用的过程中,我们就会遇到这样的问题。当然,微软也同样考虑到这一问题的,也提供了相应的解决方案,即在需要将@
作为字符输出的地方使用两个@
符号(即:@@
),这样Razor引擎在渲染时会将两个@@
标记渲染成一个@
字符,如:
@@UserName
输出结果:
@UserName
如果@
标记不是单词的开头,则可以不双写@
,如下:
My email address is: example@email.com
输出结果:
My email address is: example@email.com
位于HTML标记中的@
符号将不会被当作Razor语法标记进行处理,比如以下的邮箱地址会按原样直接输出:
<a href="mailto:example@email.com">example@email.com</a>
输出结果:
example@email.com
隐式Razor表达式
隐式Razor表达式是以@
符号开始,后面接C#代码,如下:
<p>@DateTime.Now</p>
<p>@DateTime.IsLeapYear(2016)</p>
@DateTime.Now输出结果: 当前服务器的系统时间
@DateTime.IsLeapYear(2016)输出结果为: True
在隐式表达式中,除了await
关键字外,不允许在表达式中有空格,如下的await
是允许的:
<p>@await DoSomething("hello", "world")</p>
在隐式表达式中,不允许使用泛型,因为泛型包含了括号(<>
)的HTML标记,如下的隐式表达式是错误的:
<p>@GenericMethod<int>()</p>
上面的代码产生了一个类似于以下之一的编译器错误:
- “int”元素没有关闭。所有元素都必须是自闭的或具有匹配的结束标记。
- 无法将方法组’GenericMethod’转换为非委托类型’object’。
如果要在Razor语法中调用泛型方法,则需要使用显式表达式或者使用Razor代码块
显式Razor表达式
在Razor语法中,显式表达式是由@
符号和一对圆括号共同组成,形式为:@()
。比如当前需要计算上周的当前时间,可以使用如下的Razor显式表达式实现:
<p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p>
显式表达式@()
括号内的任何内容都将作为C#代码计算并将结果输出。
正如前面提到过的,隐式表达式中不能包含空格(await关键字除外)。比如下面的代码,将不能计算出上一周的今天的结果:
<p>Last week: @DateTime.Now - TimeSpan.FromDays(7)</p>
输出结果为:
Last week: 2018-10-17 13:48:28 - TimeSpan.FromDays(7)
显式表达式可以和文本放在一起使用,用以连接文本和显式表达式的计算结果,如下:
@{
var joe = new Person("Joe", 33);
}
<p>Age@(joe.Age)</p>
如果不使用显式表达式,<p>Age@joe.Age</p>
将作为一个邮箱地址处理,渲染的结果为:<p>Age@joe.Age</p>
当使用显式表达式时,渲染结果为: <p>Age33</p>
。
在Razor页面中,显式表达式中还可以使用泛型方法,比如以下的泛型方法在显式表达式中是有效的:
<p>@(GenericMethod<int>())</p>
注意: 正如前面提到过的,泛型方法在隐式表达式中是不能使用的。
表达式编码
计算结果为字符串的C#表达式采用HTML编码。 计算结果为IHtmlContent
的C#表达式直接通过 IHtmlContent.WriteTo
渲染。计算结果不为IHtmlContent
的C#表达式通过ToString
转换为字符串,并在渲染前进行编码。
@("<span>Hello World</span>")
Razor引擎编码后的字符串为:
<span>Hello World</span>
浏览器渲染的HTML结果为:
<span>Hello World</span>
如果要在浏览器中输出HTML标记,可以使用HtmlHelper.Raw()
方法,如:
@Html.Raw("<span>Hello World</span>")
@Html.Raw
方法不会进行编码而是直接输出HTML标记,未经验证的用户输入可能包含恶意的Javascript或者其他漏洞,所以在使用@Html.Raw
方法时请谨慎。尽量避免使用@Html.Raw
来接收用户的输入。
代码块
在前文中,我们提到我代码块,那么从这里开始将详细介绍Razor语法中的代码块。
Razor语法中的代码块是以@
符号开始,代码行使用大括号{}
包裹起来。与表达式不同的是,位于代码块中的C#代码不会被渲染出来。在同一视图文件中,代码块和表达式按照定义的顺序并有着相同的作用域,如下:
@{
var quote = "未来取决于你今天做什么。 - 圣雄甘地";
}
<p>@quote</p>
@{
quote = "仇恨不能驱走仇恨,只有爱才能做到. - 马丁·路德·金";
}
<p>@quote</p>
输出结果:
<p>未来取决于你今天做什么。 - 圣雄甘地</p>
<p>仇恨不能驱走仇恨,只有爱才能做到. - 马丁·路德·金</p>
隐式转换
在代码块中的默认语言为C#,但Razor页面可以将C#代码隐式地转换为HTML代码,如下:
@{
var inCSharp = true;
<p>Now in HTML, was in C# @inCSharp</p>
}
以上代码块中首先声明了一个变量
inCSharp
,然后第二行是一行HTML标记代码,并引用了inCSharp
这个变量,在渲染的时候,Razor引擎将自动把inCSharp
变量转换成对应的值。
带分隔符的显式转换
在代码块中,在不使用HTML标记的情况下输出变量的值,可以使用Razor的<text>
标记将要呈现的字符括起来,如下:
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
<text>Name: @person.Name</text>
}
代码块中的
<text>
标记是Razor中的一个特殊语法标记,在渲染时<text>
标记并不会被输出。<text>
标记前后的空格不会显示在HTML输出中。
使用@的显式转换
在代码块中,若要以HTML的形式呈现整个行的其余内容,可以使用@:
语法:
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
@:Name: @person.Name
}
如果以上代码块中没有
@:
,会发生Razor运行时错误。
注释代码
在Razor代码块中注释代码与C#语法中的注释大致相同。
- 使用
//
可注释单行代码。 - 使用
/*...*/
注释单行或者多行代码。 - 使用
@*...*@
注释单行或者多行代码。
其中,@*...*@
的使用如下:
@{
@*我是第一行被注释掉的代码*@
@*我是第二行被注释掉的代码*@
@*
我是第一行被注释掉的代码(多行)
我是第一行被注释掉的代码(多行)
*@
}
结构/流程控制
在Razor代码块中,我们同样可以使用C#中的结构/流程控制(如:if,for,foreach,switch,while等)。
@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;
}
注意: 在使用结构/流程控制代码块是,请确保代码块内的所有HTML标记均是关闭的,否则将会发生运行编译时错误。
循环控制示例
为了循环控制的示例,我们先创建一个Person
的集合,如下:
@{
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>
}
@{ 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帮助类或者方法。 在下面的代码中,使用了@using
语句来渲染一个表单:
@using (Html.BeginForm())
{
<div>
email:
<input type="email" id="Email" value="">
<button>Register</button>
</div>
}
异常捕获与处理(@try,catch,finally)
Razor中的异常捕获/处理与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>
}
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册