所在的位置: Web开发 >> JSP >> NETCore中使用Razor模板引

NETCore中使用Razor模板引

一、简介

  在MVC以外的场景中,我们往往需要完成一些模板引擎生成代码或页面的工作;在以前我们一般常用的有Razor、NVeocity、VTemplate。虽然所有的模板系统都具有一些共同特征,但Razor却和我们前面讨论的二种视图引擎截然不同。不同于其它视图引擎,Razor在使用XML代码方面没有走得那么极端。它也不完全类似于ASPX,因为它把那些比较笨重的占位符替换成

符号接表达式或者普通的控制块。因为不需要特殊的结束标记,所以Razor最终的代码很简练。

  本篇介绍的主角是Razor,在非Core的版本中,我们常用开源的RazorEngine来解决我们的问题;但是它却没有对应.NETCore的版本。我们也只要自己动手来完成一个支持.NETCore的“模板引擎”版本。

  一般情况下使用Razor作为视图引擎要实现如下步骤:

  (1)读取模板文件-(2)生成Raozr的C#代码-(3)使用Roslyn编译代码生成程序集-(4)动态加载程序集-(5)反射调用

  

回到目录

二、非Mvc中使用Razor

  我们一般在使用Razor时都是在ASP.NETMVC中使用.cshtml来作为模板,由ASP.NETMVC的视图引擎(ViewEngine)来生成页面的代码的,总之,这里想说的是,模板引擎是独立的,它们甚至是独立的项目,由不同的公司和组织来开发。这次我们要在非Mvc中使用Raozr;首先我们要“脱离”Mvc的环境。

这里我们只在.NETCore程序中引用微软Raozr部分的程序集Microsoft.AspNetCore.Razor1.0版本,这个程序集负责将模板生成出C#代码。

1.Project.json添加引用

"dependencies":{

"Microsoft.AspNetCore.Razor":"1.0.0"

"NETStandard.Library":"1.6.0"

}

2.模板生成代码

  如下是摘录的YOYOFx框架中的一段代码,因为我们要生成代码时一般需要传入Model数据,这时需要ModelType组织代码时,要将泛型的情况考虑进去。这里的RazorViewTemplate是一个模板基类,这里包含了模板中调用的外部方法,我们常用到的如HtmlHelper、Render、Url、Raw等方法或类都是通过这个柜顶模板定义的,RazorViewTemplate是一个自定义类不需要继承其它类型,如果想扩展模板中使用的方法,只需要在这个类中加入即可。

publicclassCodeGenerateService

{

publicGeneratorResultsGenerate(TypemodelType,stringtemplate)

{

//准备临时类名,读取模板文件和Razor代码生成器

stringtemplateType="YOYO.AspNetCore.ViewEngine.Razor.RazorViewTemplate";

stringtemplateTypeName=modelType!=null?string.Format(templateType+

"{0}",modelType.FullName):templateType;

varclass_name="c"+Guid.NewGuid().ToString("N");

varhost=newRazorEngineHost(newCSharpRazorCodeLanguage(),()=newHtmlMarkupParser())

{

DefaultBaseClass=templateTypeName,

DefaultClassName=class_name,

DefaultNamespace="YOYO.AspNetCore.ViewEngine.Razor",

GeneratedClassContext=

newGeneratedClassContext("Execute","Write","WriteLiteral","WriteTo",

"WriteLiteralTo",

"RazorViewTemplate.Dynamic",newGeneratedTagHelperContext())

};

host.NamespaceImports.Add("System");

host.NamespaceImports.Add("System.Dynamic");

host.NamespaceImports.Add("System.Linq");

host.NamespaceImports.Add("System.Collections.Generic");

varengine=newRazorTemplateEngine(host);

returnengine.GenerateCode(newStringReader(template));

}

}

  通过以上代码得到GeneratorResults类型的结果,从而可以得知生成过程是否成功,错误在位置等信息。最后通过GeneratedCode属性,得到生成好的C#代码。

3.编译模板

  一般Razor的C#代码生成后,都是通过CodeDom来生成和编译代码的;.NET开源后,我们又多了一个强大的选择Roslyn,Roslyn也是支持.NETCore的,并且在整个.NET平台中,扮演着非常重要的角色,小到这种视图代码编译,大到整个项目的编译场景都有Roslyn的身影。微软最新开源的VisualStudioCode中C#插件,OmniSharp就是通过Roslyn来对项目和编辑器提供支持的。

  摘录YOYOFx代码如下:

publicTypeCompile(string   

  

  syntaxTrees:new[]{syntaxTree},

     references:ApplicationReferences);

using(varassemblyStream=newMemoryStream())   {

varresult=   在代码中可以通过CompileResult得到相应的编译错误信息,同样包括错误的信息和具体错误所在的行。

  其中注意的是LoadTypeForAssemblyStream方法,因为在.NETCore中动态加载程序集的方式跟以前有所不同AppDomain的概念现在已经消失,所以要在.NETCore动态加载程序集要使用,命名空间System.Runtime.Loader中的AssemblyLoadContext.Default.LoadFromStream方法,而在.NET4.5+中要使用Assembly.Load方法。

三、总结

  Razor不仅仅使用了动态的编译,还有一个强大的模板解析的功能。利用自定义的模板基类还可以在模板里提供一些辅助方法。这样看来Razor也算是C#DSL的一种实现了。

原文







































白癜风治疗方法
专业治疗白癜风医院



转载请注明:http://www.guyukameng.com/jsp/1390.html