Razor内幕之介绍

Razor语法的主要设计目标是:让代码和标记流能够一起工作同时尽量不与控制字符冲突。例如,下面的ASPX代码:

<ul>
     <% foreach(var p in Model.Products) { %>
     <li><%= p.Name %> ({$selection}lt;%= p.Price %>)</li>
     <% } %>
</ul>

现在,我们仅留下我们实际上关注的东西,去除额外的ASPX控制字符,处理后的代码如下:

<ul>
     foreach(var p in Model.Products) {
     <li>p.Name ($p.Price)</li>
     }
</ul>

很显然,上面的代码中并没有足够的信息来决定那些是代码,那些是标记。Razor引擎在设计的时候希望加入尽量少的信息来分辨上面代码中的代码和标记。基于Razor引擎的页面包含了代码、标记及尽量少的额外标记。因此使用C#Razor语法,上面的代码变成了:

<ul>
     @foreach(var p in Model.Products) {
     <li>@p.Name ($@p.Price)</li>
     }
</ul>

这并不是对ASPX语法的一种缝补,Razor利用对C#(或者VB)和HTML语法的充分理解来推断你要写的代码。继续上面的例子,让我们一步一步的看Razor是如何解析它的。

<ul>

Razor会一直向前解析直到遇到"@"字符,所以这行Razor会把<ul>归类为标记并转到下一行进行处理。

@foreach(var p in Model.Products) {

现在Razor发现了一个"@"字符,"@"字符是Razor中的一个魔力字符,不像ASPX中的"<%=%>",它只有一个字符,接下来解析器会计算出剩下的内容。在ASPX中,我们通过"%>"来声明代码块的结束,但是Razor并没有自己的语法来声明代码块的结束。 Razor通过最少匹配模式和基于语言的语法来决定代码块的结束。在上面的情况中,Razor知道C#中的foreach声明包含在"{"和"}"字符中,所以当foreach声明结束的时候,解析引擎返回标记状态。

<li>@p.Name ($@p.Price)</li>

刚才说过解析器在到达foreach结束之前会处于代码模式,那这段代码如何处理呢?这段代码更像是标记但我们却还在foreach声明代码块中。事实上,这是Razor使用基于语言的语法推断你意图的另一种情况,我们知道在"{"字符之后会有一些声明语句,但是,我们发现了"<li>"标记而不是声明语句,此时Razor会推断出你实际上是想切换到标记解析而不是代码解析状态。所以我们实际上得到的是有三种上下文信息的栈:首先是标记状态;通过@foreach切换到代码状态,通过"<li>"切换回标记状态;在"<li>"标记结束的时候推断出已回到foreach主体的代码状态。

}

然后解析到foreach语句块的结束"}"字符,回到标记上下文。

</ul>

接下来我们继续解析标记直到遇到下一个"@"字符或者到达文件结尾。

查看原文http://blog.andrewnurse.net/CommentView,guid,06dd7c2a-a7ee-461c-b191-83da14f0647b.aspx

时间: 2024-12-28 17:50:40

Razor内幕之介绍的相关文章

Razor内幕之解析

ASPX语法比较简单,所以ASPX解析器几乎完全是通过正则表达式来实现的.Razor解析器与ASPX解析器之间有很大不同,它实际上分为三个独立的组件: 1)理解基础HTML语法的标记解析器: 2)理解基础C#或者VB语法的代码解析器: 3)理解标记和代码如何混合的中央控制器 所以Razor解析器有三个参与者:代码解析器,标记解析器,代码解析器.三个组件相互配合,协同工作完成对Razor文档的解析.Razor解析器有三种状态,分别是:解析标记文档.解析标记块,解析代码块,任何情况下解析器都处在以上

Razor内幕之表达式

我们看一下之前例子中的代码:<li>@p.Name ($@p.Price)</li>是如何解析的. 当遇到"<li>"字符序列的时候,解析器知道正在解析一个以"</li>"为结束标志的标记.然后标记解析器在解析到结束标志之前发现了一个"@"字符,就像"@foreach"一样,再次切换到代码解析器.这时和之前的解析有些不同,C#代码解析器发现第一个标识符"p"时

Razor内幕之模板

Razor中的内联模板特性并没有被广泛讨论,但是它提供了将内联模板作为方法参数的能力.现在只有asp.net页面中的Grid helper使用了内联模板,也并没有很多关于如何创建自己的模板帮助类的文档,但是本文会对其进行一定的探讨. 首先,我们来看一下当使用内联模板的时候生成了什么代码.下面通过一个 "Repeat"的模板帮助类来说明,这个帮助类的功能是按照指定的次数重复输出模板内容.使用这个帮助类的页面内容如下: <!DOCTYPE html> <html>

《WCF技术内幕》翻译1:《WCF技术内幕》目录和作者简介

翻译序言: 我现在推荐一本很好的WCF学习书籍:<Inside Microsoft Windows Communication Foundation>.Justin Smith先生所著.2007年出版至今,在亚 马逊网站上评价也比较高.综合评价4星半.是一本不错的深入学习WCF的书籍. 我在搜索了很久以后,发现这本书目前还没有中文译本.随计划翻译.分享给国 内的WCF技术爱好者.翻译工作对我个人也是一次新的尝试,希望这本书的翻译 能给大家的学习带来帮助.另外如有技术问题或翻译不当,都可以留言交

IT时代周刊:优酷投资视频搜索挑战百度权威

百度没有想到,扶持旗下视频网站奇艺的同时,却也为自己带来了一个竞争对手. 日前,视频网站优酷推出视频垂直搜索品牌"搜库",希望此举能帮助优酷和其他视频网站摆脱传统搜索引擎对它们的控制.这一举动,意味着优酷将与百度在视频搜索方面展开正面竞争. 对于公司的这一险招,优酷网CTO姚键坦言并不惧怕来自百度视频搜索方面的压力.在他看来,与传统搜索引擎相比,在视频领域拥有成熟运营经验的优酷对于视频用户行为的把握度会更高,在提供视频搜索内容时可以更加贴近用户的需求. 作为一个垂直搜索引擎,搜库的视频

《WCF技术内幕》20:第2部分_第5章_消息:Message类型介绍

第5章:消息 System.ServiceModel.Channels.Message抽象类型是Microsoft Windows Communication Foundation (WCF)里通信的基本单位.尽管Message类型使用在 WCF 程序里,但是WCF的开发人员却不需要直接接触Message.因此,可以不与任 何Message的实例交互就能写出一个功能丰富的WCF程序.但是,虽然你的代码没 有直接与Message对象交互,记住WCF基础结构也在背后忙于创建.发送.接受或 者其它处理

《WCF技术内幕》翻译5:第1部分_第1章_蓝月亮:WCF介绍和本章小结

WCF介绍 在上世纪90年代微软和其他公司看到了互联的普遍需求和面向服务的普遍概 念.那时,还没有被普遍接受的消息标准,结果,就没有平台.应用程序编程接 口 API.或者能够让开发者轻易创建面向服务的应用系统的运行时环境.技术上 说,是可以创建面向服务的应用,但是开发工具和运行时环境的功能使得这一切 看来相当困难.幸运的是,微软和其他厂商开始定义一个可以产生统一消息结构 的基础架构.最终努力的结果就是WS-*规范.于此同时,微软也在制定可以给开 发者提供他们开发支持WS-*规范的面向服务应用的开

Linux系统鲜为人知的12大内幕介绍

据国外媒体报道,Linux似乎没有得到人们充分的爱戴.苹果的OS X和微软的Windows等操作系统一直是人们关注的重点,但事实上,免费且是开放源的Linux操作系统尽管被人遗忘,却一直在支持着巨大数量的日常或独特的项目,并影响着人们的生活.Linux基金 (Linux Foundation)执行主任吉姆·扎姆林(Jim Zemlin)声称:"你们每天都在使用Linux,不过,你们对此并不知情. Linux已经成为我们生活的一大基础部门. Linux运行着飞行航班控制系统.银行系统等,而且甚至还

批处理技术内幕 ECHO命令介绍_DOS/BAT

众所周知,如果echo后面跟一个环境变量,但是该变量却为空时,相当于不加任何参数的echo,即输出当前echo是on还是off.很多文章或者教程给出的解决方案都是在echo后面加一个点号echo.,这样就会输出空行. 复制代码 代码如下: @echo off echo %demon.tw% :: ECHO is off. echo.%demon.tw% pause据我所知,用echo输出空行至少有十种方法: 复制代码 代码如下: @echo off echo= echo, echo; echo+