Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项。简洁的语法与.NET Framework 结合,广泛应用于ASP.NET MVC 项目。Razor Pad是一个编辑Razor脚本的工具,脱离于ASP.NET 和Visual Studio。

微软已经有一套模板引擎T4,在设计ASP.NET MVC 3时又设计一套模板引擎Razor,对开发者而言是多一种选择,但同时也增加学习成本,至今我都没有时间和精力将Code Smith的模板转化为T4的模板。

Razor  从模板到.NET 代码

以cshtml为后缀名的为Razor模板,可以混合脚本语言和Html代码,以呈现为ASP.NET Page页面。

来看下面的Razor脚本片段,它以div的格式输出Posts对象的标题:

  1. <div>
  2. @foreach(var post in Posts) {
  3. <div>@post.Title</div>
  4. }
  5. </div>

Razor引擎分析上面的脚本,产生如下所示的Xml文本片段

  1. <Document>
  2. <Markup><div>\r\n\t</Markup>
  3. <Statement>
  4. <Transition>@</Transition>
  5. <Code>foreach(var post in posts) { </Code>
  6. <Markup>
  7. <Markup><div></Markup>
  8. <Expression>
  9. <Transition>@</Transition>
  10. <ImplicitExpression>post.Title</ImplicitExpression>
  11. </Expression>
  12. <Markup></div></Markup>
  13. </Markup>
  14. <Code> } </Code>
  15. <Markup></div></Markup>
  16. </Statement>
  17. <Markup>\r\n</div></Markup>
  18. </Document>

以空格或是@作为区域(block)的分割符,将Razor解析成一个表达式树。@在Razor模板中的用法相当灵活,可以用于表达式的求值,或是定义代码块。

然后产生.NET代码,上面的脚本,会产生如下的.NET代码类型

  1. namespace Razor {
  2. public class __CompiledTemplate {
  3. public __CompiledTemplate() {
  4. }
  5. public override void Execute() {
  6. WriteLiteral("<div>\r\n\t");
  7. @foreach(var post in posts) {
  8. WriteLiteral("<div>");
  9. Write(post.Title);
  10. WriteLiteral("</div>");
  11. }
  12. WriteLiteral("\r\n</div>");
  13. }
  14. }
  15. }
  1.  

最后,应用CodeDom API编译上面的代码,调用Execute方法输出结果。

Razor API

一开始接触这项技术时,以为是ASP.NET MVC的一个开源项目,接触之后才知道它是.NET Framework API中的类型,几年没有做Web开发,ASP.NET技术发展的确实很快。

System.Web.Razor.Parser.RazorParser

RazorParser用于解析脚本,但是它对Html,CS,VB脚本一无所知。MarkupParser用于解析Html标记,CSharpCodeParser用于解析包含C#代码的标记,相应的VBCodeParser则用于解析包含VB脚本的标记,

System.Web.Razor.Generator.RazorCodeGenerator

根据传入的Markup Parser,产生代码。与Parser相似,它也有二个与标记语言相关的类型,CSharpRazorCodeGenerator 和VBRazorCodeGenerator,用于处理标记包含的脚本。

System.Web.Razor.RazorEngineHost

System.Web.Razor.RazorTemplateEngine

引擎宿主,用于接受标记脚本,产生.NET 类型的代码。

把上面的内容综合起来,写一个例子程序,来看这些API的用法。

创建脚本宿主

  1. var language = new CSharpRazorCodeLanguage();
  2. var host = new RazorEngineHost(language) {
  3. DefaultBaseClass = "CustomTemplateBase",
  4. DefaultClassName = "DemoTemplate",
  5. DefaultNamespace = "ProgrammingRazor",
  6. };
  1.  

添加Razor脚本引擎,读取标记(Markup)文件

  1. RazorTemplateEngine engine = new RazorTemplateEngine(host);
  2. GeneratorResults razorResult = engine.GenerateCode("C:\\Script.txt");

编译标记文件生成的类型,生成Code Dom 脚本

  1. CompilerResults compilerResults =
  2. new CSharpCodeProvider()
  3. .CompileAssemblyFromDom(
  4. new CompilerParameters(/*...*/),
  5. razorResult.GeneratedCode
  6. );

执行生成的程序集类型,获取结果

  1. var template = (CustomTemplateBase)Activator.CreateInstance(“ProgrammingRazor.DemoTemplate”);
  2. template.Execute();
  1.  

Razor Pad程序的功能,也是用的这个基本思路来展来的。

Razor Pad是一个开放源码的程序,你可以从网址http://razorpad.codeplex.com中获取它的源代码。

理解模板引擎Razor 的原理(转载)的更多相关文章

  1. 理解模板引擎Razor 的原理

    Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.简洁的语法与.NET Framework 结合,广泛应用于ASP.NET MVC 项目.Razor Pad是一 ...

  2. 【转链接】Handlebars模板引擎以及浅谈模板引擎的实现原理

    什么叫做“模板引擎“?我是这么理解的:就是对一些待填入数据的占位符的解析.如果你使用过Python的django框架,那你肯定是模板一点也不陌生.模板引擎就是解析模板的,把后端数据塞到前端页面模板. ...

  3. [2018-08-25]模板引擎Razor Engine 用法示例

    好久没写博客了,回宁波后最近几个月一直忙些线下的事情. 敲代码方面脱产有阵子了,生疏了,回头一看,这行业果然更新飞快. 最近线下的事情基本忙完,准备开始干回老本行,最重要的一件事就是升级abplus库 ...

  4. doT.js模板引擎及基础原理

    时至今日,基于后端JavaScript(Node.js)和MVC思想也开始流行起来.模板引擎是数据和页面分离工作中最重要的一环,在各大门户网站均有利用到模板引擎. 模板引擎有很多种,但是原理了解也是非 ...

  5. 模板引擎的简单原理template

    ​ var templateStr = "我的名字叫<%=name%>我是一只小狗,今年<%=age%>岁."; var data = { name:'旺财 ...

  6. (转)浅谈dedecms模板引擎工作原理及自定义标签

    理解织梦模板引擎有什么意义?一方面可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步.理解织梦会使我们写php代码时更顺手,同时能学习一些php代码的组织方式. 这似乎 ...

  7. 浅谈dedecms模板引擎工作原理及其自定义标签

    浅谈dedecms模板引擎工作原理: 理解织梦模板引擎有什么意思? 可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步. 理解织梦会使我们写PHP代码是更顺手,同时能学 ...

  8. PHP的模板引擎smarty原理是什么(整理)

    PHP的模板引擎smarty原理是什么(整理) 一.总结 一句话总结:其实所有的模板引擎的工作原理是差不多的,无非就是在php程序里面用正则匹配将模板里面的标签替换为php代码从而将两者混合为一个ph ...

  9. JavaScript模板引擎原理,几行代码的事儿

    一.前言 什么是模板引擎,说的简单点,就是一个字符串中有几个变量待定.比如: var tpl = 'Hei, my name is <%name%>, and I\'m <%age% ...

随机推荐

  1. 不可不知的C#基础 4. 延迟加载 -- 提高性能

    延迟加载(lazy loading) 设计模式是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据(读取属性值)的时候,才真正执行数据加载操作. 有效使用它可以大大提高系统性能. ...

  2. Java6 String.substring()方法的内存泄露

    substring(start,end)在Java编程里面经常使用,没想到如果使用不当,会出现内存泄露. 要了解substring(),最好的方法便是查看源码(jdk6): /** * <blo ...

  3. Android开发探秘之四:利用Intent实现数据传递

    在Android开发过程中,很多人都熟悉Intent,这是个用于在多个View之间共享数据的类.本节主要是继承上节,通过点选ListView中的文本,把文本中的URL加载到一个新的页面上,并且打印出来 ...

  4. 教你怎么fan qiang 进国内看视频而不受限制

    这一周难得今天闲一点,写日志也不知道写啥,谈爱情?...没得谈.思前想后还是在这儿带给大家点福利吧,主要是针对在国外生活的孩纸们看国内视频总是提示被限制的问题,qq音乐也是.     或许大家有听过f ...

  5. 如何抛出未认证(Unauthorized=401)异常代码

    throw new System.ServiceModel.Web.WebFaultException<string>("\"mes\":\"认证信 ...

  6. XP明年就被停止技术支持,这会带来什么?谈谈如何做决策

    XP是MS的一款老牌操作系统,相信大家都不陌生,甚至还有继续使用的人,当然了,在虚拟机里用它也是很好用的,不过,再漂亮的姑娘,也有嫁人的时候,作为XP的父母,MS微软明年四月将停止支持有十多年历史的 ...

  7. [c#基础]值类型和引用类型的Equals,==的区别

    引言 最近一个朋友正在找工作,他说在笔试题中遇到Equals和==有什么区别的题,当时跟他说如果是值类型的,它们没有区别,如果是引用类型的有区别,但string类型除外.为了证实自己的说法,也研究了一 ...

  8. JavaScript基础---Cookie

    内容提纲: 1.cookie 2.cookie局限性 3.其他存储 发文不易,转载请注明出处链接,谢谢! 随着Web越来越复杂,开发者急切的需要能够本地化存储的脚本功能.这个时候,第一个出现的方案:c ...

  9. iOS - 获取手机中所有图片

    1 #import <AssetsLibrary/AssetsLibrary.h> /** 6 * ALAssetsLibrary.h 代表资源库(所有的视频,照片) 7 ALAssets ...

  10. Java基础-String 存储机制管理

    JVM运行的时候,将内存分为两个部分,一部分是堆,一部分是栈.堆中存放的是创建对象,而栈中存放的则是方法调用过程中的局部变量或引用.在设计JAVA字符串对象内存实现的时候,在堆中又开辟了一块很小的内存 ...