RazorEngine
官網網址:http://razorengine.codeplex.com
圖一 System.Web.Razor的參考,只有載入基本的三個組件
使用範例(部份直接使用官網的範例)
一般用法
string template = "Hello @Model.Name! Welcome to Razor!"; string result2 = Razor.Parse(template, new { Name = "World" }, "Sample");
最後一個參數Name是選項參數,但建議給值因為關係到快取,如果有給,下次使用相同名稱的範本會用快取的,而且關係到範本的Include,雖然RazorEngine不能用RanderAction或RanderPartial但有提供Include可以載入,也是使用此Name為關鍵字。
使用.cshtml檔案
只要是副檔名為.cshtml,就算不在ASP.NET MVC3專案中,編輯.cshtml的方式都相同(但缺web.config中的設定,所以有些功能出不來),當然範本檔副檔名不一定要為.cshtml,但有IDE支援總比沒有好。
只是寫法要變,因為ASP.NET MVC 3的BaseType是System.Web.Mvc.WebViewPage,而RazorEngine的BaseType是RazorEngine.Templating.TemplateBase,除了Model屬性外其他的Html、Url、Ajax等等屬性都不沒有,但是C#的語法都支援。
test.cshtml:
<html> <head> <title>Hello @Model.Name</title> </head> <body> Email: @Model.Email </body> </html>
var model = new { Name = "World", Email = "someone@somewhere.com" }; string result = Razor.Parse(File.ReadAllText("test.cshtml"), model, "test");
進階用法
Template的Include
RazorEngine雖然不支援RanderAction或RanderPartial,不過他有提供Include方法,載入已經Compile(或Parse)過的範本,以下是使用範例:
string template1 = "Hello @Model.Name"; string template2 = "This is my sample template, @Include(\"Template1\",Model)"; Razor.Compile(template1, "Template1"); string result = Razor.Parse(template2, new { Name = "Zach" });
內嵌方法
如果只有單一個範本會用到的方法可以使用內嵌方法,以下是使用範例:
string template = @" @helper myMethod(string name) { <div>Hello @name</div> } <html> <head> <title></title> </head> <body> @myMethod(Model.Name) Email: @Model.Email </body> </html>"; string result = Razor.Parse(template, new { Name = "Zach", Email = "test@163.com" });
BaseType
每一個範本,最後都會使用System.Web.Razor.RazorTemplateEngine編譯成Class,而且繼承BaseType,所以BaseType決定了範本能使用的功能,如果還是不清楚请看下面例子:
@"@{var name=""Would"";} Hello @name!!";
這些內容經剖析後會變成這樣
namespace RezorCodeDomSample { public class MyTemplateRsult : RezorCodeDomSample.MyTemplate { public MyTemplateRsult() { } public override void Execute() { var name = "Would"; WriteLiteral("Hello "); Write(name); WriteLiteral("!!\r\n"); } } }
這樣有比較清楚BaseType的功用了嗎?
所以如果希望所有的範本都可以使用的功能,可以繼承RazorEngine.Templating.TemplateBase,將擴充功能寫在子類別,然後註冊子類別,以下是使用範例:
public abstract class MyCustomTemplateBase<T> : TemplateBase<T> { public string ToUpperCase(string name) { return name.ToUpper(); } } class Program { static void Main(string[] args) { //注册子类 Razor.SetTemplateBase(typeof(MyCustomTemplateBase<>)); string template = @"Hello @Model.Name! Welcome to Razor! My name in UPPER CASE is: @ToUpperCase(Model.Name) "; string result = Razor.Parse(template, new { Name = "Zach" }); } }
載入組件與命名空間
RazorEngine註冊CodeDom所使用的組件是使用AppDomain.CurrentDomain.GetAssemblies()的方式,所以只要在專案中所參考的組件,範本中都可以使用,還有為了增加撰寫的便利性,可以增加命名空間,以下是使用範例:
Razor.DefaultTemplateService.Namespaces.Add("System.Xml"); string template = @"@{ var xml = new XmlDocument(); xml.LoadXml(Model); Write(xml.InnerXml); }"; string result = Razor.Parse<string>(template, "<Test>test</Test>");
設定檔
跟ASP.NET MVC 3一樣,命名空間或BaseType等等都可以寫在設定檔中,詳情請參考官網
增加區段
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <configSections> <section name="razorEngine" type="RazorEngine.Configuration.RazorEngineConfigurationSection, RazorEngine" requirePermission="false" /> </configSections> </configuration>
增加設定
<razorEngine activator="RazorEngineSamples.Activators.MySampleActivator, RazorEngineSamples" factory="RazorEngine.Web.WebCompilerServiceFactory, RazorEngine.Web"> <namespaces> <add namespace="System.Linq" /> </namespaces> <templateServices default="myCustomTemplateService"> <add name="myCustomTemplateService1" language="CSharp" /> <add name="myCustomTemplateService2" templateBase="MyTemplateBase"/> </templateServices> </razorEngine>
TemplateService可以讓某些範本使用不同的設定,以下是使用範例:
var service = Razor.Services["myCustomTemplateService"]; string result = service.Parse("Hello @Model.Name", new { Name = "World" });
From : http://www.dotblogs.com.tw/wadehuang36/archive/2011/08/07/razor-template-engine.aspx