用Razor語法寫範本-RazorEngine組件介紹【转——非常好,可以用它来代替NVelocity】

RazorEngine

官網網址:http://razorengine.codeplex.com

在找到RazorEngine之前曾經想過其他的方案,如T4與V8 Engine載jquery.template,但T4如果要獨立於MSBuild或Visual Studio執行有點麻煩,而V8 Engine我又不想在Class Library專案中放一堆js檔,後來就想到Razor,因為Razor的相關處理都是寫在System.Web.Razor,雖然Namespace叫System.Web,但根本沒有載入任何的System.Web相關的組件(如圖一),所以我肯定它可以獨立在非Web環境於中使用,在研究如何運用的期間,就發現早在去年就有人寫好放在CodePlex上,我太落伍了。

圖一 System.Web.Razor的參考,只有載入基本的三個組件

註:有興趣知道如何使用System.Web.Razor產生結果(基本上都是CodeDom),我所知道就有四套,小弟這一篇[ASP.NET MVC]Razor Views 預編譯(Pre-Compile)[1]-加快第一次執行回應速度介紹的二個Extension與本篇的RazorEngine與ASP.NET MVC 3使用的System.Web.WebPages.Razor,除了System.Web.WebPages.Razor外都是Open Source的可以下載Code來觀摩。

下面的範例,將展示如果只單獨使用System.Web.Razor.dll,如何產生結果(有點累,還是用別人的組件比較好)。

namespace RezorCodeDomSample
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            //簡單的範本
            string template = @"@{var name=""Would"";}
                                Hello @name!!";

            var input = new System.IO.StringReader(template);

            //產生Razor的TemplateEngine
            var host = new RazorEngineHost(new CSharpRazorCodeLanguage());
            host.DefaultBaseClass = "RezorCodeDomSample.MyTemplate";
            host.DefaultNamespace = "RezorCodeDomSample";
            host.DefaultClassName = "MyTemplateResult";
            var engine = new RazorTemplateEngine(host);

            //取得結果的CodeDom
            var code = engine.GenerateCode(input);
            var codeType = code.GeneratedCode.Namespaces[0].Types[0];
            var codeProvider = new CSharpCodeProvider();

            //將CodeDom輸出到檔案中
            //CodeGeneratorOptions options = new CodeGeneratorOptions();
            //options.BlankLinesBetweenMembers = true;
            //System.IO.StringWriter sw = new System.IO.StringWriter();
            //codeProvider.GenerateCodeFromCompileUnit(code.GeneratedCode, sw, options);
            //File.WriteAllText("c:\\text.cs", sw.ToString());

            //將CodeDom編譯
            var options = new CompilerParameters()
            {
                GenerateInMemory = true,
                GenerateExecutable = false,
            };
            options.ReferencedAssemblies.Add(typeof(Program).Assembly.Location);
            var asselby = codeProvider.CompileAssemblyFromDom(options, code.GeneratedCode);

            //執行Template
            var type = asselby.CompiledAssembly.GetType("RezorCodeDomSample.MyTemplateResult");
            var ins = Activator.CreateInstance(type) as MyTemplate;
            ins.Execute();
            Console.Write(ins.Reault);
        }
    }

    //如果沒有Base類會不好處理
    public class MyTemplate
    {
        private StringBuilder sb = new StringBuilder();

        public virtual void Execute()
        {
        }

        public void Write(object value)
        {
            sb.Append(value);
        }

        public void WriteLiteral(object value)
        {
            sb.Append(value);
        }

        public string Reault
        {
            get { return sb.ToString(); }
        }
    }
}

使用範例(部份直接使用官網的範例)

一般用法

string template = "Hello @Model.Name! Welcome to Razor!";
string result = 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#的語法都支援。

string result = Razor.Parse(File.ReadAllText("test.cshtml"), new { IsVip = true, Name = "Wade" });

進階用法

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 = "Wade" });

內嵌方法

如果只有單一個範本會用到的方法可以使用內嵌方法,以下是使用範例:

string template = @"
@helper MyMethod(string name) {
  Hello @name
}

@MyMethod(Model.Name)! Welcome to Razor!";

string result = Razor.Parse(template, new { Name = "World" });

BaseType

每一個範本,最後都會使用System.Web.Razor.RazorTemplateEngine編譯成Class,而且繼承BaseType,所以BaseType決定了範本能使用的功能,如果還是不清楚以第一個範例為例:

@"@{var name=""Would"";}
  Hello @name!!";

這些內容經剖析後會變成這樣

//與第一個範例拿掉註解後所產生的test.cs檔案相同
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.ToUpperCase();
  }
}

//註冊子類
Razor.SetTemplateBase(typeof(MyCustomTemplateBase<>));

string template = "My name in UPPER CASE is: @ToUpperCase(Model.Name)";
string result = Razor.Parse(template, new { Name = "Matt" });

載入組件與命名空間

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" });

原文地址:http://www.dotblogs.com.tw/wadehuang36/archive/2011/08/07/razor-template-engine.aspx

时间: 2024-10-12 18:31:20

用Razor語法寫範本-RazorEngine組件介紹【转——非常好,可以用它来代替NVelocity】的相关文章

為 Swift 代碼編寫含有 Mardown 語法的文檔

原文:Documenting Your Swift Code in Xcode Using Markdown 作者:GABRIEL THEODOROPOULOS 译者:kmyhy 在 Xcode 7 的所有新功能中,有一個最引人注目的新功能,能够讓你以更好的方式来书写代码文檔.從 Xcode 7 開始,開發者終於可以在他們的文檔中使用强大 Markdown 語法來進行富文本编辑了,Markdown 語法用一些特殊的關鍵字來描述文檔中的不同部分,比如參數.函數返回值等,從而使這些結構顯示出不同的樣

Makefile 語法簡介

有稍稍在 Linux 下碰過程式設計的開發者應該會知道,make 是用來將程式碼.函式庫.標頭檔及其它資源檔 build 成最終成果(即:最終的應用程式)的超強力輔助工具. 當然了,並不是非得動用到 make 才能 build 程式,或許有什麼程式設計魔人喜歡什麼都自己手動進行:但利用 make 及其參考檔(輸入檔案)Makefile將會讓整個編譯工作輕鬆許多.若您曾經打包過 Debian Package,那麼應該會發現 debuan/rule 這個檔案的語法和 Makefile 幾乎是一模一樣

Java學習筆記(基本語法)

本文件是以學習筆記的概念為基礎,用於自我的複習紀錄,不過也開放各位的概念指證.畢竟學習過程中難免會出現觀念錯誤的問題.也感謝各位的觀念指證. 安裝JDK 在Oracle網站中找自己系統的JDK下載位置 設定 PATH windows10 =>本機=>右鍵內容=>進階系統設定=>進階=>環境變數 設定 第一個程式Hello World 12345678910111213 public class { /** 程式的預設的進入點, 必須是public static, 另外這是Ja

Delphi APP 開發入門(六)Object Pascal 語法初探

Delphi APP 開發入門(六)Object Pascal 語法初探 分享: Share on facebookShare on twitterShare on google_plusone_share 閲讀次數:3442 發表時間:2014/06/10 tags: 行動開發 教學 App Delphi XE6 Android iOS Delphi APP 開發入門(五)GPS 定位功能 << 前情 經過前面五週幾乎每週可以寫出一個簡單App後,大家都可以感受到Delphi強大的開發威力!

何解決 LinqToExcel 發生「無法載入檔案或組件」問題何解決 LinqToExcel 發生「無法載入檔案或組件」問題

在自己的主機上透過 Visual Studio 2013 與 IISExpress 開發與測試都還正常,但只要部署到測試機或正式機,就是沒辦法順利執行,卡關許久之後找我協助.我發現錯誤訊息確實很「一般」,訊息是:「 無法載入檔案或組件 'LinqToExcel' 或其相依性的其中之一. 試圖載入格式錯誤的程式. 」或是英文版的「 Could not load file or assembly 'LinqToExcel' or one of its dependencies. An attempt

C# 語法---文件讀寫操作

文件讀寫操作 System.IO命名空間有著不同的類,用於執行各種文件操作 1.File  類 提供用於創建.複製.刪除.移動和打開單一文件的靜態方法.Flie的一些方法可以返回FileStream和StreamWriter對象 常用方法: Open(String path,FileMode mode)  以讀/寫 訪問權限打開指定路徑上的FileStream   參數 path 要打開的文件   mode 用於指定文件不存在時是否創建該文件,并確定保留還是覆蓋 Create(String) 

IOS基礎_Block語法的簡單使用

開始學IOS的時候沒怎麼接觸過block語句,在後來用到的越來越多,就不得不學了,剛開始理解比較困難的,然後自己做了一個例子就慢慢理解了,www.ios5.online不說廢話了,上代碼: 正常的簡單地申明調用一個block語句是這樣的: //申明 int (^yxpBlock)(int, int) =^(int a ) {return a*a ;}; 說明:返回值(^語句塊名稱)(傳人參數類型)=^(傳人參數){主體}: //調用 int result = square(5); 我建了一個測試

PHP &amp; Delphi 語法

明 C(区分大小写) Delphi(不区分大小写) PHP(区分大小写) 整型变量的定义 1 2 3 4 5 6 7 char a = 'a';         /* 8位有符号*/ int a=10;             /* 16位有符号*/ unsigned int a = 10;  /* 16位无符号*/ short a = 10;         /* 16位有符号*/ unsigned short a = 10;/* 16位无符号*/ long a = 10;         

sql server存儲過程語法

-- 变量的声明,sql里面声明变量时必须在变量前加@符号    DECLARE @I INT -- 变量的赋值,变量赋值时变量前必须加set    SET @I = 30 -- 声明多个变量    DECLARE @s varchar(10),@a INT -- Sql 里if语句    IF 条件 BEGIN        执行语句    END    ELSE BEGIN        执行语句    END                DECLARE @d INT    set @d