ASP.NET MVC 解析模板生成静态页一(RazorEngine)

简述

Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项。在早期的MVC版本中默认使用的是ASPX模板引擎,Razor在语法上的确不错,用起来非常方便,简洁的语法与.NET Framework 结合,广泛应用于ASP.NET MVC 项目。

我们在很多项目开发中会常常用到页面静态化,页面静态化有许多方式,最常见的就是类似很多PHP CMS种使用的 标签替换的方式(如:帝国CMS、EcShop等),还有很多都是伪静态,伪静态我们就不做过多解释,通过路由或Url重写来实现就可以了。Razor为我们提供了更加方便的模板解析方式,任何东西都是两方面的,技术也是如此,Razor解析模板虽然更加方便、简洁,但是对于模板制作人员来说也是有一定的技术要求,或者对于开发一套模板制作功能来说,考虑的要更多一些。我们不再去探究这些问题,我们更注重哪种技术更容易、更方便、更好的满足我们项目的需求。

如何使用RazorEngine

今天来简单介绍一下如何使用RazorEngine解析模板生成静态页面,RazorEngine它是基于微软的Razor之上,包装而成的一个可以独立使用的模板引擎。也就是说,保留了Razor的模板功能,但是使得Razor脱离于Asp.net MVC,能够在其它应用环境下使用,项目地址:https://github.com/Antaris/RazorEngine

首先我们去codeplex上下两个需要的dll http://razorengine.codeplex.com

看到网上很多介绍RazorEngine的基础用法的,讲解的都比较详细,对于RazorEngine运行原理很清晰,我们在这里就不重复介绍了。写这篇文章是对于很多新手同学来说比较喜欢“拿来主义”,基本的用法原理都能看懂,但是如何应用到项目中还是有些不是很清晰,我们只讲讲如何在项目中运用。

本文分为两部分:第一个部分,基本的单数据模型模板解析;第二部分,面向接口的多数据模型模板解析

第一个部分 基本的单数据模型模板解析

一、我们创建一个MVC项目,并且添加上面的两个DLL引用,然后我们新建一个简单的文章类

  1. public class Articles
  2. {
  3. /// <summary>
  4. /// 文章ID
  5. /// </summary>
  6. public int Id { get; set; }
  7. /// <summary>
  8. /// 文章标题
  9. /// </summary>
  10. public string Title { get; set; }
  11. /// <summary>
  12. /// 文章内容
  13. /// </summary>
  14. public string Content { get; set; }
  15. /// <summary>
  16. /// 作者
  17. /// </summary>
  18. public string Author { get; set; }
  19. /// <summary>
  20. /// 发布时间
  21. /// </summary>
  22. public DateTime CreateDate { get; set; }
  23. }

二、我们新建一个Razor的Html模板

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5. <title>@Model.Title</title>
  6. </head>
  7. <body>
  8. <h1>@Model.Title</h1>
  9. <p>作者:@Model.Author - 发布时间:@Model.CreateDate</p>
  10. <p>@Raw(Model.Content)</p>
  11. </body>
  12. </html>

说明:Model就是我们的文章实体类  在MVC的试图页cshtml中 我们一般都是在控制器里传递这个实体类 然后在视图页中 @model Models.Articles 来接收这个实体类 然后通过“@Model.”来输出内容,在Razor模板中是一样的,只是不用@model Models.Articles 来接收了,其它的语法跟在.cshtml试图页中是一样的,这么说多余了,因为写法不一样他就不是Razor了

三、我们写一个方法来获取模板页的Html代码

  1. /// <summary>
  2. /// 获取页面的Html代码
  3. /// </summary>
  4. /// <param name="url">模板页面路径</param>
  5. /// <param name="encoding">页面编码</param>
  6. /// <returns></returns>
  7. public string GetHtml(string url, System.Text.Encoding encoding)
  8. {
  9. byte[] buf = new WebClient().DownloadData(url);
  10. if (encoding != null) return encoding.GetString(buf);
  11. string html = System.Text.Encoding.UTF8.GetString(buf);
  12. encoding = GetEncoding(html);
  13. if (encoding == null || encoding == System.Text.Encoding.UTF8) return html;
  14. return encoding.GetString(buf);
  15. }
  16.  
  17. /// <summary>
  18. /// 获取页面的编码
  19. /// </summary>
  20. /// <param name="html">Html源码</param>
  21. /// <returns></returns>
  22. public System.Text.Encoding GetEncoding(string html)
  23. {
  24. string pattern = @"(?i)\bcharset=(?<charset>[-a-zA-Z_0-9]+)";
  25. string charset = Regex.Match(html, pattern).Groups["charset"].Value;
  26. try { return System.Text.Encoding.GetEncoding(charset); }
  27. catch (ArgumentException) { return null; }
  28. }

四、我们写一个方法 用于生成Html静态页

  1. /// <summary>
  2. /// 创建静态文件
  3. /// </summary>
  4. /// <param name="result">Html代码</param>
  5. /// <param name="createpath">生成路径</param>
  6. /// <returns></returns>
  7. public bool CreateFileHtmlByTemp(string result, string createpath)
  8. {
  9. if (!string.IsNullOrEmpty(result))
  10. {
  11. if (string.IsNullOrEmpty(createpath))
  12. {
  13. createpath = "/default.html";
  14. }
  15. string filepath = createpath.Substring(createpath.LastIndexOf(@"\"));
  16. createpath = createpath.Substring(0, createpath.LastIndexOf(@"\"));
  17. if (!Directory.Exists(createpath))
  18. {
  19. Directory.CreateDirectory(createpath);
  20. }
  21. createpath = createpath + filepath;
  22. try
  23. {
  24. FileStream fs2 = new FileStream(createpath, FileMode.Create);
  25. StreamWriter sw = new StreamWriter(fs2, new System.Text.UTF8Encoding(false));//去除UTF-8 BOM
  26. sw.Write(result);
  27. sw.Close();
  28. fs2.Close();
  29. fs2.Dispose();
  30. return true;
  31. }
  32. catch { return false; }
  33. }
  34. return false;
  35. }

五、我们来写个方法调用静态模板,并且传递数据模型实体类 创建Html静态页

  1. /// <summary>
  2. /// 解析模板生成静态页
  3. /// </summary>
  4. /// <param name="temppath">模板地址</param>
  5. /// <param name="path">静态页地址</param>
  6. /// <param name="t">数据模型</param>
  7. /// <returns></returns>
  8. public bool CreateStaticPage(string temppath, string path, RazorEngineTemplates.Models.Articles t)
  9. {
  10. try
  11. {
  12. //获取模板Html
  13. string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8);
  14.  
  15. //初始化结果
  16. string result = string.Empty;
  17.  
  18. //解析模板生成静态页Html代码
  19. result = Razor.Parse(TemplateContent, t);
  20.  
  21. //创建静态文件
  22. return CreateFileHtmlByTemp(result, path);
  23. }
  24. catch (Exception e)
  25. {
  26. throw e;
  27. }
  28. }

好了,大功告成,是不是很简单。

这里只是一个很简单的应用,没有读取数据,也没有列表,只有一个文章数据模型,下一部分我们将介绍 多模型模板解析,因为是多模型 所以 生成静态页面的时候 就不是传递一个具体模型实体类 我们会用到 反射,通过反射模型属性 获取数据,有不熟悉反射的可以提前研究一下,也可以直接看下一部分的反射代码也很简单的。

第二部分 面向接口的多数据模型模板解析

这一部分,我们介绍使用接口来解析模板,包括列表等多种模型解析,用到了Spring注入和反射还有接口等,有不熟悉的可以百度搜一下或者评论留言。

我们接着上面的示例,我们新建两个类库 一个是存放数据模型的 我们叫Domain;另外一个是接口和实现类的 我们叫Service,然后我们添加他们之间的引用

一、我们在Domain下创建几个测试类

Articles - 文章测试类

Company - 公司测试类

Column - 栏目测试类

TemplateView - 模型解析类(这个是不是比较弱智?我也没深入研究多个模型怎么反射出来 所以 我加了这么个算是公用的类 没有对应的数据表 只是解析模板的时候 作为中间件用用)

  1.   public class Articles
  2. {
  3. /// <summary>
  4. /// 文章ID
  5. /// </summary>
  6. public int Id { get; set; }
  7. /// <summary>
  8. /// 文章标题
  9. /// </summary>
  10. public string Title { get; set; }
  11. /// <summary>
  12. /// 文章内容
  13. /// </summary>
  14. public string Content { get; set; }
  15. /// <summary>
  16. /// 作者
  17. /// </summary>
  18. public string Author { get; set; }
  19. /// <summary>
  20. /// 发布时间
  21. /// </summary>
  22. public DateTime CreateDate { get; set; }
  23. }
  24.   public class Company
  25. {
  26. /// <summary>
  27. /// 公司Id
  28. /// </summary>
  29. public int Id { get; set; }
  30. /// <summary>
  31. /// 公司名称
  32. /// </summary>
  33. public string CompanyName { get; set; }
  34. /// <summary>
  35. /// 公司电话
  36. /// </summary>
  37. public string CompanyTel { get; set; }
  38. /// <summary>
  39. /// 联系人
  40. /// </summary>
  41. public string ContectUser { get; set; }
  42. /// <summary>
  43. /// 创建时间
  44. /// </summary>
  45. public DateTime CreateDate { get; set; }
  46. }
  47.   public class Column
  48. {
  49. /// <summary>
  50. /// 栏目ID
  51. /// </summary>
  52. public int Id { get; set; }
  53. /// <summary>
  54. /// 栏目名称
  55. /// </summary>
  56. public string Title { get; set; }
  57. /// <summary>
  58. /// 文章列表
  59. /// </summary>
  60.  
  61. public virtual ICollection<Articles> Articles { get; set; }
  62. }
  63.   public class TemplateView
  64. {
  65. /// <summary>
  66. /// ID
  67. /// </summary>
  68. public int Id { get; set; }
  69. /// <summary>
  70. /// 标题
  71. /// </summary>
  72. public string Title { get; set; }
  73. /// <summary>
  74. /// 内容
  75. /// </summary>
  76. public string Content { get; set; }
  77. /// <summary>
  78. /// 作者
  79. /// </summary>
  80. public string Author { get; set; }
  81. /// <summary>
  82. /// 时间
  83. /// </summary>
  84. public DateTime CreateDate { get; set; }
  85. /// <summary>
  86. /// 公司名称
  87. /// </summary>
  88. public string CompanyName { get; set; }
  89. /// <summary>
  90. /// 公司电话
  91. /// </summary>
  92. public string CompanyTel { get; set; }
  93. /// <summary>
  94. /// 联系人
  95. /// </summary>
  96. public string ContectUser { get; set; }
  97. /// <summary>
  98. /// 文章列表
  99. /// </summary>
  100. public virtual ICollection<Articles> Articles { get; set; }
  101. }

二、我们在Service下创建一个基础操作接口以及其实现类(里面的很多方法 比如:获取页面的Html代码、获取页面的编码以及创建静态文件等 是没有必要写在接口的 这个可以写到公用的类库里,因为这里就用到这么几个方法 所以我没有加公用类库 就直接写在这里面了)

  1. /// <summary>
  2. /// 基础操作接口
  3. /// </summary>
  4. /// <typeparam name="T"></typeparam>
  5. public interface IRepository<T> where T : class
  6. {
  7. /// <summary>
  8. /// 解析模板生成静态页
  9. /// </summary>
  10. /// <param name="temppath">模板地址</param>
  11. /// <param name="path">静态页地址</param>
  12. /// <param name="t">数据模型</param>
  13. /// <returns></returns>
  14. bool CreateStaticPage(string temppath, string path, T t);
  15.  
  16. /// <summary>
  17. /// 获取页面的Html代码
  18. /// </summary>
  19. /// <param name="url">模板页面路径</param>
  20. /// <param name="encoding">页面编码</param>
  21. /// <returns></returns>
  22. string GetHtml(string url, System.Text.Encoding encoding);
  23.  
  24. /// <summary>
  25. /// 获取页面的编码
  26. /// </summary>
  27. /// <param name="html">Html源码</param>
  28. /// <returns></returns>
  29. System.Text.Encoding GetEncoding(string html);
  30.  
  31. /// <summary>
  32. /// 创建静态文件
  33. /// </summary>
  34. /// <param name="result">Html代码</param>
  35. /// <param name="createpath">生成路径</param>
  36. /// <returns></returns>
  37. bool CreateFileHtmlByTemp(string result, string createpath);
  38. }
  39. /// <summary>
  40. /// 基础接口实现类
  41. /// </summary>
  42. /// <typeparam name="T"></typeparam>
  43. public abstract class RepositoryBase<T> : IRepository<T> where T : class
  44. {
  45. /// <summary>
  46. /// 解析模板生成静态页
  47. /// </summary>
  48. /// <param name="temppath">模板地址</param>
  49. /// <param name="path">静态页地址</param>
  50. /// <param name="t">数据模型</param>
  51. /// <returns></returns>
  52. public bool CreateStaticPage(string temppath, string path, T t)
  53. {
  54. try
  55. {
  56. //实例化模型
  57. var Entity = new Domain.TemplateView();
  58.  
  59. //获取模板Html
  60. string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8);
  61. //初始化结果
  62. string result = "";
  63.  
  64. //反射赋值
  65. Type typeT = t.GetType();
  66. Type typeEn = Entity.GetType();
  67.  
  68. System.Reflection.PropertyInfo[] propertyinfosT = typeT.GetProperties();
  69.  
  70. foreach (System.Reflection.PropertyInfo propertyinfoT in propertyinfosT)
  71. {
  72. System.Reflection.PropertyInfo propertyinfoEn = typeEn.GetProperty(propertyinfoT.Name);
  73. if (propertyinfoEn != null && propertyinfoT.GetValue(t, null) != null)
  74. {
  75. propertyinfoEn.SetValue(Entity, propertyinfoT.GetValue(t, null), null);
  76. }
  77. }
  78.  
  79. //很多时候 我们并没有创建复杂的主外键关系 例如栏目下的文章 我们仅仅是在文章表中添加了一个所属栏目ID的字段
  80. //并没有创建关联 这种情况下 我们直接获取栏目的时候 是获取不到文章列表的
  81. //包括很多自定义的模型和字段 比如 文章的内容 可能不跟文章一个表 而是一个单独的大数据字段表 这种情况下 我们的
  82. //TemplateView.Content就需要单独获取一下另一个数据模型里的 这个文章的内容 这种时候 我们可以在这里重新给他赋值
  83.  
  84. //如 传入的模型是 文章
  85. //if(t is Domain.Articles)
  86. //{
  87. // Entity.Content= 查询大数据字段表中这篇文章的内容;
  88.  
  89. //}
  90.  
  91. result = Razor.Parse(TemplateContent, Entity);
  92.  
  93. return CreateFileHtmlByTemp(result, path);
  94. }
  95. catch (Exception e)
  96. {
  97. throw e;
  98. }
  99. }
  100.  
  101. /// <summary>
  102. /// 获取页面的Html代码
  103. /// </summary>
  104. /// <param name="url">模板页面路径</param>
  105. /// <param name="encoding">页面编码</param>
  106. /// <returns></returns>
  107. public string GetHtml(string url, System.Text.Encoding encoding)
  108. {
  109. byte[] buf = new WebClient().DownloadData(url);
  110. if (encoding != null) return encoding.GetString(buf);
  111. string html = System.Text.Encoding.UTF8.GetString(buf);
  112. encoding = GetEncoding(html);
  113. if (encoding == null || encoding == System.Text.Encoding.UTF8) return html;
  114. return encoding.GetString(buf);
  115. }
  116.  
  117. /// <summary>
  118. /// 获取页面的编码
  119. /// </summary>
  120. /// <param name="html">Html源码</param>
  121. /// <returns></returns>
  122. public System.Text.Encoding GetEncoding(string html)
  123. {
  124. string pattern = @"(?i)\bcharset=(?<charset>[-a-zA-Z_0-9]+)";
  125. string charset = Regex.Match(html, pattern).Groups["charset"].Value;
  126. try { return System.Text.Encoding.GetEncoding(charset); }
  127. catch (ArgumentException) { return null; }
  128. }
  129.  
  130. /// <summary>
  131. /// 创建静态文件
  132. /// </summary>
  133. /// <param name="result">Html代码</param>
  134. /// <param name="createpath">生成路径</param>
  135. /// <returns></returns>
  136. public bool CreateFileHtmlByTemp(string result, string createpath)
  137. {
  138. if (!string.IsNullOrEmpty(result))
  139. {
  140. if (string.IsNullOrEmpty(createpath))
  141. {
  142. createpath = "/default.html";
  143. }
  144. string filepath = createpath.Substring(createpath.LastIndexOf(@"\"));
  145. createpath = createpath.Substring(0, createpath.LastIndexOf(@"\"));
  146. if (!Directory.Exists(createpath))
  147. {
  148. Directory.CreateDirectory(createpath);
  149. }
  150. createpath = createpath + filepath;
  151. try
  152. {
  153. FileStream fs2 = new FileStream(createpath, FileMode.Create);
  154. StreamWriter sw = new StreamWriter(fs2, new System.Text.UTF8Encoding(false));//去除UTF-8 BOM
  155. sw.Write(result);
  156. sw.Close();
  157. fs2.Close();
  158. fs2.Dispose();
  159. return true;
  160. }
  161. catch { return false; }
  162. }
  163. return false;
  164. }
  165. }

三、我们分别创建 文章管理、公司管理、栏目管理的接口和实现类 并且他们都集成基础操作

  1.    /// <summary>
  2. /// 文章管理
  3. /// </summary>
  4.   public interface IArticleManage:IRepository<Domain.Articles>
  5. {
  6. }
  7. public class ArticleManage:RepositoryBase<Domain.Articles>,IArticleManage
  8. {
  9. }
  10.  
  11.   /// <summary>
  12. /// 公司管理
  13. /// </summary>
  14. public interface ICompanyManage:IRepository<Domain.Company>
  15. {
  16. }
  17.   public class CompanyManage:RepositoryBase<Domain.Company>,ICompanyManage
  18. {
  19. }
  20.  
  21.   //栏目管理
  22. public interface IColumnManage:IRepository<Domain.Column>
  23. {
  24. }
  25.   public class ColumnManage:RepositoryBase<Domain.Column>,IColumnManage
  26. {
  27. }

四、注入Xml

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <objects xmlns="http://www.springframework.net">
  3. <description>Spring注入Service,容器指向本层层封装的接口</description>
  4. <object id="Service.ArticleManage" type="Service.ArticleManage,Service" singleton="false">
  5. </object>
  6. <object id="Service.ColumnManage" type="Service.ColumnManage,Service" singleton="false">
  7. </object>
  8. <object id="Service.CompanyManage" type="Service.CompanyManage,Service" singleton="false">
  9. </object>
  10. </objects>

五、我们分别初始化一个文章类、一个公司类(没有管理数据表,它下面没有文章列表 栏目模型我就不初始化了,怎么输出列表 大家可以参考下 栏目模板)

  1. public class HomeController : Controller
  2. {
  3. /// <summary>
  4. /// 声明一下注入接口
  5. /// </summary>
  6. public IArticleManage ArticleManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.ArticleManage") as IArticleManage;
  7. public ICompanyManage CompanyManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.CompanyManage") as ICompanyManage;
  8. public IColumnManage ColumnManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.ColumnManage") as IColumnManage;
  9.  
  10. public ActionResult Index()
  11. {
  12. //初始化一个文章数据模型
  13. var entityArticle = new Domain.Articles() { Id = 1, Title = "这里是文章标题", Content = "<span style=\"color:red;\">这里是文章内容</span>", Author = "张三", CreateDate = DateTime.Now };
  14.  
  15. //初始化一个公司数据模型
  16. var entityCompany = new Domain.Company() { Id = 1, CompanyName = "这里是公司名称", CompanyTel = "公司电话", ContectUser = "张三", CreateDate = DateTime.Now };
  17.  
  18. //调用方法生成静态页面
  19. ArticleManage.CreateStaticPage(Server.MapPath("/Templates/Temp_article.html"), Server.MapPath("/Pages/news/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "1.html"), entityArticle);
  20. CompanyManage.CreateStaticPage(Server.MapPath("/Templates/Temp_company.html"), Server.MapPath("/Pages/news/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "2.html"), entityCompany);
  21.  
  22. return View();
  23. }
  24.  
  25. public ActionResult About()
  26. {
  27. ViewBag.Message = "Your application description page.";
  28.  
  29. return View();
  30. }
  31.  
  32. public ActionResult Contact()
  33. {
  34. ViewBag.Message = "Your contact page.";
  35.  
  36. return View();
  37. }
  38.  
  39. }

六、这是测试的简单的文章模板、公司模板和栏目模板

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>@Model.Title</title>
  6. </head>
  7. <body>
  8. <h1>@Model.Title</h1>
  9. <p>作者:@Model.Author - 发布时间:@Model.CreateDate</p>
  10. <p>@Raw(Model.Content)</p>
  11. </body>
  12. </html>
  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5. <title></title>
  6. </head>
  7. <body>
  8. <p>公司名称:@Model.CompanyName</p>
  9. <p>公司电话:@Model.CompanyTel</p>
  10. <p>联系人:@Model.ContectUser</p>
  11. <p>创建时间:@Model.CreateDate</p>
  12. </body>
  13. </html>
  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5. <title></title>
  6. </head>
  7. <body>
  8. <p>栏目标题: @Model.Title</p>
  9. <p>
  10. 文章列表
  11. <ul>
  12. @foreach(var item in @Model.Articles)
  13. {
  14. <li>
  15. <a href="">
  16. <span>@item.Title</span>
  17. <span>@item.Author</span>
  18. <span>@item.CreateDate</span>
  19. </a>
  20. </li>
  21. }
  22. </ul>
  23. </p>
  24. </body>
  25. </html>

我们运行一下,大功告成~~~

         

怎么排序?怎么获取前几条?怎么格式化日期时间?怎么分页?

这可是Razor啊,这都不需要再多讲了吧,简单一说,如果你传入数据前没有事先排序或者获取前几条,这些操作要做模板里操作 那跟在.cshtml里基本是一样的

  1. @foreach(var item in @Model.ListColumn)
  2. {
  3.  
  4. <div >
  5. @if (@item.LinkUrl==null)
  6. {
  7. <ul>
  8. @foreach(var article in @item.COM_ARTICLE.Take(15).OrderByDescending(p=>p.UpDateDate))
  9. {
  10.  
  11. <li>
  12. <a href="@article.LinkUrl" class="gd-a">
  13. <div>@article.Title</div></a>
  14. </li>
  15. }
  16. </ul>
  17. }
  18. else
  19. {
  20.  
  21. }
  22. </div>
  23. }

应用还是很广泛的,而且解析代码相对于标签替换来说十分简洁、高效。有时间可以多研究研究,改天有空写一个模板替换标签的供大家参考一下。

还是那句老话,这篇文章仅仅是个人的一些理解和实现,可能中间会出现一些不合理的地方或是错误,请大家指正,我们共同学习研究。

Demo是用VS 2013写的

下载:第一部分百度网盘  第二部分百度网盘

原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com

 
分类: ASP.NET MVC

NET MVC RazorEngine 解析模板生成静态页的更多相关文章

  1. ASP.NET MVC 解析模板生成静态页一(RazorEngine)

    简述 Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.在早期的MVC版本中默认使用的是ASPX模板引擎,Razor在语法上的确不错,用起来非常方便,简洁的语法 ...

  2. C# 用模板生成静态页

    最近在研究静态页输出的问题,找了一些资料.做了一个简单的模板模式的静态输出 模板代码: <html xmlns="http://www.w3.org/1999/xhtml"& ...

  3. ASP.NET MVC 利用Razor引擎生成静态页

    实现原理及步骤: 1.通过ViewEngines.Engines.FindView查找到对应的视图,如果是部分视图,则用:ViewEngines.Engines.FindPartialView: 2. ...

  4. mvc分页生成静态页,mvc生成静态页

    http://blog.csdn.net/xxj_jing/article/details/7899125 分页生成静态页 http://www.cnblogs.com/luanyilin/archi ...

  5. 基于PHP生成静态页的实现方法

    t1.php 复制代码 代码如下: <?php// 方法一根据模版生成静态页面// replaceTemplateString函数用于替换模板中指定字符串function replaceTemp ...

  6. ThinkPHP生成静态页buildHtml方法

    原来ThinkPHP自带了生成静态页的函数buildHtml,使用起来很方便!最新的手册里没写这个方法,向大家介绍一下. PHP 1 2 3 4 5 6 7 8 9 10 11     protect ...

  7. 生成静态页面的PHP类

    生成静态页面的PHP类: 复制代码代码如下: <?php   class html   {    var $dir; //dir for the htmls(without/)    var $ ...

  8. tp 生成静态页

    $this->fetch()返回的是html 可以直接写入到HTML文件内生成静态页

  9. dedesmc 手机端生成静态页

    dedesmc 手机端生成静态页 1.首先下载插件,下载地址:https://pan.baidu.com/s/1Nfx_KBYuxRkZ7VzoPxy28g 密码:83x7 2.进入 dedecms ...

随机推荐

  1. PowerMock mock私有方法

    import java.util.Random; public class CodeWithPrivateMethod { public void meaningfulPublicApi() { if ...

  2. 基于visual Studio2013解决C语言竞赛题之0609矩阵处理

     题目

  3. 如何查询一个库文件属于哪个rpm包

    1.如果这个库文件已经存在 使用rpm命令: # rpm -qf  /file/path  (绝对路径) 例如: # rpm -qf /lib/libm.so.6 glibc-2.12-1.47.el ...

  4. GDSOI2015 task4 ACU

    题目大意 只要你有耐心看完题目,你就可以得到以下模型: 给出一个有向图,有若干询问,每次询问对于某条边\((v,u)\),求删掉这条边后,\(v\)到\(u\)的最短路. 算法1 暴力出奇迹,期望得分 ...

  5. html5游戏开发--"动静"结合用地图块拼成大地图 & 初探lufyl

    一.前言   本次教程将向大家讲解如何用html5将小地图块拼成大地图,以及如何用现有的高级html5游戏开发库件lufylegend.js开发游戏.   首先让我们来了解了解如何用html5实现动画 ...

  6. telerik 控件 SCRIPT5007: 无法获取未定义或 null 引用的属性“documentElement” (IE 文档模式)

    IE对盒模型的渲染在 Standards Mode和Quirks Mode是有很大差别的,在Standards Mode下对于盒模型的解释和其他的标准浏览器是一样,但在Quirks Mode模式下则有 ...

  7. FastDFS的学习与使用(大量帖子)

    http://www.oschina.net/p/fastdfs http://bbs.chinaunix.net/forum-240-1.html

  8. string和byte[]的转换 (C#)

    原文 string和byte[]的转换 (C#) string类型转成byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBytes  ...

  9. GAE+bottle+jinja2+beaker快速开发demo - Python,GAE - language - ITeye论坛

    GAE+bottle+jinja2+beaker快速开发demo - Python,GAE - language - ITeye论坛     :GAE+bottle+jinja2+beaker快速开发 ...

  10. 九度OnlineJudge之1017:还是畅通工程

    题目描述:     某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可 ...