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

[ASP.net教程]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引用,然后我们新建一个简单的文章类

public class Articles  {    /// <summary>    /// 文章ID    /// </summary>    public int Id { get; set; }    /// <summary>    /// 文章标题    /// </summary>    public string Title { get; set; }    /// <summary>    /// 文章内容    /// </summary>    public string Content { get; set; }    /// <summary>    /// 作者    /// </summary>    public string Author { get; set; }    /// <summary>    /// 发布时间    /// </summary>    public DateTime CreateDate { get; set; }  }

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

<!DOCTYPE html><html "http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>  <title>@Model.Title</title></head><body>  <h1>@Model.Title</h1>  <p>作者:@Model.Author - 发布时间:@Model.CreateDate</p>  <p>@Raw(Model.Content)</p></body></html>

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

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

 /// <summary>    /// 获取页面的Html代码    /// </summary>    /// <param name="url">模板页面路径</param>    /// <param name="encoding">页面编码</param>    /// <returns></returns>    public string GetHtml(string url, System.Text.Encoding encoding)    {      byte[] buf = new WebClient().DownloadData(url);      if (encoding != null) return encoding.GetString(buf);      string html = System.Text.Encoding.UTF8.GetString(buf);      encoding = GetEncoding(html);      if (encoding == null || encoding == System.Text.Encoding.UTF8) return html;      return encoding.GetString(buf);    }    /// <summary>    /// 获取页面的编码    /// </summary>    /// <param name="html">Html源码</param>    /// <returns></returns>    public System.Text.Encoding GetEncoding(string html)    {      string pattern = @"(?i)\bcharset=(?<charset>[-a-zA-Z_0-9]+)";      string charset = Regex.Match(html, pattern).Groups["charset"].Value;      try { return System.Text.Encoding.GetEncoding(charset); }      catch (ArgumentException) { return null; }    }

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

 /// <summary>    /// 创建静态文件    /// </summary>    /// <param name="result">Html代码</param>    /// <param name="createpath">生成路径</param>    /// <returns></returns>    public bool CreateFileHtmlByTemp(string result, string createpath)    {      if (!string.IsNullOrEmpty(result))      {        if (string.IsNullOrEmpty(createpath))        {          createpath = "/default.html";        }        string filepath = createpath.Substring(createpath.LastIndexOf(@"\"));        createpath = createpath.Substring(0, createpath.LastIndexOf(@"\"));        if (!Directory.Exists(createpath))        {          Directory.CreateDirectory(createpath);        }        createpath = createpath + filepath;        try        {          FileStream fs2 = new FileStream(createpath, FileMode.Create);          StreamWriter sw = new StreamWriter(fs2, new System.Text.UTF8Encoding(false));//去除UTF-8 BOM          sw.Write(result);          sw.Close();          fs2.Close();          fs2.Dispose();          return true;        }        catch { return false; }      }      return false;    }

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

/// <summary>    /// 解析模板生成静态页    /// </summary>    /// <param name="temppath">模板地址</param>    /// <param name="path">静态页地址</param>    /// <param name="t">数据模型</param>    /// <returns></returns>    public bool CreateStaticPage(string temppath, string path, RazorEngineTemplates.Models.Articles t)    {      try      {        //获取模板Html        string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8);        //初始化结果        string result = string.Empty;        //解析模板生成静态页Html代码        result = Razor.Parse(TemplateContent, t);        //创建静态文件        return CreateFileHtmlByTemp(result, path);      }      catch (Exception e)      {        throw e;      }    }

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

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

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

由于时间原因,这一部分我会稍后贴出

 

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

Demo是用VS 2013写的 

下载:第一部分百度网盘

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