你的位置:首页 > ASP.net教程

[ASP.net教程]RazorEngine在非MVC下的使用,以及使用自定义模板


---恢复内容开始---

RazorEngine模板引擎大大的帮助了我们简化字符串的拼接与方法的调用,开源之后,现在在简单的web程序,winform程序,甚至控制台程序都可以利用它来完成。

但如何在使用中调用方法和使用自定义模板呢?来看这样一个例子

 

1 string str="hello @Model.Name";2 string parse=Razor.Prase(str,new {Name="Tom"});3 Console.WriteLine(parse);

这里就输出了hello Tom的内容

以下为了方便,我们不试用控制台,把str扩展到cshtml文件来做模板。

 

我们首先来写一个RazorHelper的类,里面的Parse方法用来封装

 1 namespace RazorEngineTest 2 { 3   public class RazorHelper 4   { 5     public static string Parse<T>(HttpContext context,string virtualPath,T Model) 6     { 7       string path = context.Server.MapPath(virtualPath); 8       string rawhtml = File.ReadAllText(path); 9       //设置cacheName缓存。10       string cacheName = path + File.GetLastWriteTime(path);11       string parseHtml = Razor.Parse<T>(rawhtml, Model, cacheName);12       return parseHtml;13     }14   }15 }

这样,在使用我们只需在cshtml也这么写就行,通过Model.方法即可

<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>  <title></title>  <meta charset="utf-8" /></head><body>  @Model.Name</body></html>

 

那么现在我想在cshtml里调用razor中的方法,就类似

 @Raw("<h1>Raw</h1>")

即可调用Razor中的Raw方法,返回一个h1标题的test

 

 

那么为了简化起见,我们又如何使用自定义的方法呢?

我总结两种方法:

1.直接使用我们之前创造的RazorHelper。在这个类后我们接着写,

比如,这两个方法。

 1      /// <summary> 2     /// 用于输出原始html 3     /// </summary> 4     /// <param name="value">参数</param> 5     /// <returns></returns> 6     public static IEncodedString RawHtml(string value) 7     { 8       return new RawString(value); 9     }10     /// <summary>11     /// 用于输出转义后字符12     /// </summary>13     /// <param name="value">参数</param>14     /// <returns></returns>15     public static HtmlEncodedString Text(string value)16     {17       return new HtmlEncodedString(value);18     }

这样我们在cshtml页就可以通过以下方式调用,第一个RawHtml是类似之前自带的Raw()方法输出,输出原始字符,Text方法则输出转义后字符。

   @using RazorEngineTest  @RazorHelper.RawHtml("<h1>RazorHelper.RawHtml</h1>")  @RazorHelper.Text("List<T>")

 

那么通过这种方式一我们就可以实现自定义的方法。

 

---------------------------------------分割线----------------------------------

当然除此之外,我更加推荐方法二,这种方法更为方便,且调用时更为简洁。也就是使用Razor自定义模板

由于在Razor中,存在一个TemplateBase<T>这个TemplateBase就是我们的基类模板,可见它实现了Itemplate接口,

而且经过反编译,看出它Write,WriteLiteral方法是用来进行字符串拼接的。没错Razor内部却是进行的是字符串拼接,只不过比我们的拼接要厉害的多。

 

大概是这种方式

1 public string Execute(object Model)2 {3     stringBuilder sb = new stringBuilder(string.Empty);4     sb.append("<html><head></head><body>");5     sb.append(Model.Name);6     sb.append("</body></html>");7     return sb.toString();    8 }

不过我们现在要自己创建模板和方法。当然我们不可能自己再重新造轮子,所以我们使用造好的BaseTemplate

 

让我们的MyTemplate<T>继承自TemplateBase<T>

那么在MyTemplate<T>里面,就可以写我们自己的方法了

为了更好理解我们还是用上述例子。

 1 public class MyTemplate<T>:TemplateBase<T> 2   { 3     //用于输出原始html 4     public IEncodedString OutputRawString(string value) 5     { 6       return new RawString(value); 7     } 8     //输出转义后内容 9     public HtmlEncodedString OutputHtmlString(string value)10     {11       return new HtmlEncodedString(value);12     }13   }

 

不过我们在使用前需要注册模板,也在razorHelper里定义,方便调用

1 public static void SetTemplate(Type templateType)2     {3       Razor.SetTemplateService(new TemplateService(new TemplateServiceConfiguration()4       {5         BaseTemplateType = typeof(MyTemplate<>)6       }));7 8     }

使用时,在之前注册一下就好

1 RazorHelper.SetTemplate(typeof(MyTemplate<>));2 string parse = RazorHelper.Parse(context, "~/Razor1.cshtml", new { Name = "Jerry" });

我们在cshtml也就可以这么写了

@OutputRawString("<h1>MyTemplate</h1>")即可

这就是自定义模板和自定义方法怎么使用。

 

 

可是问题如下,如果我们有很多方法,都放在自定义模板下,则会变得非常臃肿,

比如@OutputRawString @Add @AddHtml @ChangeString @ChangeHtml.....等等越来越多,那么我们用一种方式把它分类如何。

我们可以自定义一个类,比如MyRazorHtmlHelper,里面有几个方法

 1 public class MyRazorHtmlHelper 2   { 3     //输出原始html 4     public IEncodedString RawString(string value) 5     { 6       return new RawString(value); 7     } 8     //输出一个checkbox 9     public IEncodedString CheckBox(string id,string value,bool IsChecked)10     {11       StringBuilder sb = new StringBuilder(string.Empty);12       sb.Append("<input type='checkbox' id=").Append(id).Append("' value='").Append("' ");13       if (IsChecked)14       {15         sb.Append("checked");16       }17       sb.Append("/>");18       return new RawString(sb.ToString());19     }20   }

之后如何在我们的MyTemplate使用呢?

我们可以实例化一个MyRazorHtmlHelper对象,然后返回它就行

 1 private MyRazorHtmlHelper htmlhelper; 2     public MyRazorHtmlHelper Html //写调用的名称 3     { 4       get 5       { 6         if (htmlhelper==null) 7         { 8           htmlhelper = new MyRazorHtmlHelper(); 9         }10         return htmlhelper;11       }12     }

 

这样我们就可以通过 @Html.方法名来进行调用了

比如

@Html.CheckBox("cb","Gender",true)这是checkbox

这样就可以让我们对不同方法进行分类,类似nameSpace一样,使用非常方便。

 

这就是开源的RazorEngine的强大,以及自定义模板的用法

放上源码

 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5   <title></title> 6   <meta charset="utf-8" /> 7 </head> 8 <body> 9   @Model.Name10   @Raw("<h1>Raw</h1>")11  12   @using RazorEngineTest13   @RazorHelper.RawHtml("<h1>RazorHelper.RawHtml</h1>")14   @RazorHelper.Text("List<T>")15 16   @OutputRawString("<h1>MyTemplate</h1>")17 18   @Html.CheckBox("cb","Gender",true)这是checkbox19 </body>20 </html>

Razor1.cshtml
 1  public void ProcessRequest(HttpContext context) 2     { 3       context.Response.ContentType = "text/html"; 4  5       RazorHelper.SetTemplate(typeof(MyTemplate<>)); 6       string parse = RazorHelper.Parse(context, "~/Razor1.cshtml", new { Name = "Jerry" }); 7  8       context.Response.Write(parse); 9 10     }

Razor1.ashx.cs
 1 using RazorEngine; 2 using RazorEngine.Configuration; 3 using RazorEngine.Templating; 4 using RazorEngine.Text; 5 using System; 6 using System.Collections.Generic; 7 using System.IO; 8 using System.Linq; 9 using System.Text;10 using System.Web;11 12 namespace RazorEngineTest13 {14   public class MyRazorHtmlHelper15   {16     //输出原始html17     public IEncodedString RawString(string value)18     {19       return new RawString(value);20     }21     //输出一个checkbox22     public IEncodedString CheckBox(string id,string value,bool IsChecked)23     {24       StringBuilder sb = new StringBuilder(string.Empty);25       sb.Append("<input type='checkbox' id=").Append(id).Append("' value='").Append("' ");26       if (IsChecked)27       {28         sb.Append("checked");29       }30       sb.Append("/>");31       return new RawString(sb.ToString());32     }33   }34   public class MyTemplate<T>:TemplateBase<T>35   {36     private MyRazorHtmlHelper htmlhelper;37     public MyRazorHtmlHelper Html38     {39       get40       {41         if (htmlhelper==null)42         {43           htmlhelper = new MyRazorHtmlHelper();44         }45         return htmlhelper;46       }47     }48     //用于输出原始html49     public IEncodedString OutputRawString(string value)50     {51       return new RawString(value);52     }53     //输出转义后内容54     public HtmlEncodedString OutputHtmlString(string value)55     {56       return new HtmlEncodedString(value);57     }58   }59   public class RazorHelper60   {61     public static void SetTemplate(Type templateType)62     {63       Razor.SetTemplateService(new TemplateService(new TemplateServiceConfiguration()64       {65         BaseTemplateType = templateType66       }));67 68     }69     public static string Parse<T>(HttpContext context,string virtualPath,T Model)70     {71       string path = context.Server.MapPath(virtualPath);72       string rawhtml = File.ReadAllText(path);73       //设置cacheName缓存。74       string cacheName = path + File.GetLastWriteTime(path);75       string parseHtml = Razor.Parse<T>(rawhtml, Model, cacheName);76       return parseHtml;77     }78     /// <summary>79     /// 用于输出原始html80     /// </summary>81     /// <param name="value">参数</param>82     /// <returns></returns>83     public static IEncodedString RawHtml(string value)84     {85       return new RawString(value);86     }87     /// <summary>88     /// 用于输出转义后字符89     /// </summary>90     /// <param name="value">参数</param>91     /// <returns></returns>92     public static HtmlEncodedString Text(string value)93     {94       return new HtmlEncodedString(value);95     }96 97   }98 }

RazorHelper.cs