ASP.NET MVC使用RazorEngine解析模板生成静态页


当前第2页 返回上一页

/// <summary>
 /// 基础操作接口
 /// </summary>
 /// <typeparam name="T"></typeparam>
 public interface IRepository<T> where T : class
 {
 /// <summary>
 /// 解析模板生成静态页
 /// </summary>
 /// <param name="temppath">模板地址</param>
 /// <param name="path">静态页地址</param>
 /// <param name="t">数据模型</param>
 /// <returns></returns>
 bool CreateStaticPage(string temppath, string path, T t); 

 /// <summary>
 /// 获取页面的Html代码
 /// </summary>
 /// <param name="url">模板页面路径</param>
 /// <param name="encoding">页面编码</param>
 /// <returns></returns>
 string GetHtml(string url, System.Text.Encoding encoding);

 /// <summary>
 /// 获取页面的编码
 /// </summary>
 /// <param name="html">Html源码</param>
 /// <returns></returns>
 System.Text.Encoding GetEncoding(string html);

 /// <summary>
 /// 创建静态文件
 /// </summary>
 /// <param name="result">Html代码</param>
 /// <param name="createpath">生成路径</param>
 /// <returns></returns>
 bool CreateFileHtmlByTemp(string result, string createpath);
 }
/// <summary>
 /// 基础接口实现类
 /// </summary>
 /// <typeparam name="T"></typeparam>
 public abstract class RepositoryBase<T> : IRepository<T> where T : class
 {
 /// <summary>
 /// 解析模板生成静态页
 /// </summary>
 /// <param name="temppath">模板地址</param>
 /// <param name="path">静态页地址</param>
 /// <param name="t">数据模型</param>
 /// <returns></returns>
 public bool CreateStaticPage(string temppath, string path, T t)
 {
  try
  {
  //实例化模型
  var Entity = new Domain.TemplateView();

  //获取模板Html
  string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8);
  //初始化结果
  string result = "";

  //反射赋值
  Type typeT = t.GetType();
  Type typeEn = Entity.GetType();

  System.Reflection.PropertyInfo[] propertyinfosT = typeT.GetProperties();

  foreach (System.Reflection.PropertyInfo propertyinfoT in propertyinfosT)
  {
   System.Reflection.PropertyInfo propertyinfoEn = typeEn.GetProperty(propertyinfoT.Name);
   if (propertyinfoEn != null && propertyinfoT.GetValue(t, null) != null)
   {
   propertyinfoEn.SetValue(Entity, propertyinfoT.GetValue(t, null), null);
   }
  }

  //很多时候 我们并没有创建复杂的主外键关系 例如栏目下的文章 我们仅仅是在文章表中添加了一个所属栏目ID的字段
  //并没有创建关联 这种情况下 我们直接获取栏目的时候 是获取不到文章列表的
  //包括很多自定义的模型和字段 比如 文章的内容 可能不跟文章一个表 而是一个单独的大数据字段表 这种情况下 我们的
  //TemplateView.Content就需要单独获取一下另一个数据模型里的 这个文章的内容 这种时候 我们可以在这里重新给他赋值

  //如 传入的模型是 文章
  //if(t is Domain.Articles)
  //{
  // Entity.Content= 查询大数据字段表中这篇文章的内容;
   
  //}

  result = Razor.Parse(TemplateContent, Entity);

  return CreateFileHtmlByTemp(result, path);
  }
  catch (Exception e)
  {
  throw e;
  }
 }

 /// <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; }
 }

 /// <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;
 }
 }

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

   /// <summary>
 /// 文章管理
 /// </summary>
   public interface IArticleManage:IRepository<Domain.Articles>
 {
 }
 public class ArticleManage:RepositoryBase<Domain.Articles>,IArticleManage
 {
 }

  /// <summary>
 /// 公司管理
 /// </summary>
 public interface ICompanyManage:IRepository<Domain.Company>
 {
 }
  public class CompanyManage:RepositoryBase<Domain.Company>,ICompanyManage
 {
 }

  //栏目管理
 public interface IColumnManage:IRepository<Domain.Column>
 {
 }
  public class ColumnManage:RepositoryBase<Domain.Column>,IColumnManage
 {
 }

四、注入Xml

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

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

public class HomeController : Controller
 {
 /// <summary>
 /// 声明一下注入接口
 /// </summary>
 public IArticleManage ArticleManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.ArticleManage") as IArticleManage;
 public ICompanyManage CompanyManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.CompanyManage") as ICompanyManage;
 public IColumnManage ColumnManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.ColumnManage") as IColumnManage;


 public ActionResult Index()
 {
  //初始化一个文章数据模型
  var entityArticle = new Domain.Articles() { Id = 1, Title = "这里是文章标题", Content = "<span style=\"color:red;\">这里是文章内容</span>", Author = "张三", CreateDate = DateTime.Now };

  //初始化一个公司数据模型
  var entityCompany = new Domain.Company() { Id = 1, CompanyName = "这里是公司名称", CompanyTel = "公司电话", ContectUser = "张三", CreateDate = DateTime.Now };

  //调用方法生成静态页面
  ArticleManage.CreateStaticPage(Server.MapPath("/Templates/Temp_article.html"), Server.MapPath("/Pages/news/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "1.html"), entityArticle);
  CompanyManage.CreateStaticPage(Server.MapPath("/Templates/Temp_company.html"), Server.MapPath("/Pages/news/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "2.html"), entityCompany);

  return View();
 }

 public ActionResult About()
 {
  ViewBag.Message = "Your application description page.";

  return View();
 }

 public ActionResult Contact()
 {
  ViewBag.Message = "Your contact page.";

  return View();
 }
 
 }

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

<!DOCTYPE html>
<html xmlns="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>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <title></title>
</head>
<body>
 <p>公司名称:@Model.CompanyName</p>
 <p>公司电话:@Model.CompanyTel</p>
 <p>联系人:@Model.ContectUser</p>
 <p>创建时间:@Model.CreateDate</p>
</body>
</html>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <title></title>
</head>
<body>
 <p>栏目标题: @Model.Title</p>
 <p>
 文章列表
 <ul>
  @foreach(var item in @Model.Articles)
  {
  <li>
  <a >
   <span>@item.Title</span>
   <span>@item.Author</span>
   <span>@item.CreateDate</span>
  </a>
  </li>
  }
 </ul>
 </p>
</body>
</html>

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

        

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

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

@foreach(var item in @Model.ListColumn)
{

 <div >
@if (@item.LinkUrl==null)
 {
 <ul>
@foreach(var article in @item.COM_ARTICLE.Take(15).OrderByDescending(p=>p.UpDateDate))
{

<li>
  <a  class="gd-a">
  <div>@article.Title</div></a>
  </li>
}
 </ul>
 }
 else
 {

 }
</div>
}

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

还是那句老话,这篇文章仅仅是个人的一些理解和实现,可能中间会出现一些不合理的地方或是错误,请大家指正,我们共同学习研究。
以上就是本文的全部内容,希望大家喜欢。
原文地址:http://yuangang.cnblogs.com

更多ECSHOP内容来自木庄网络博客


标签:ECSHOP

返回前面的内容

相关阅读 >>

让你的php7更快之hugepage用法分析

ECSHOP完美解决deprecated preg_replace()报错的问题

javascript弹出层输入框(示例代码)

微信小程序自定义ypicker组件实现省市区三级联动功能

c#权限管理和设计浅谈

php环境无法上传文件的解决方法

人物:戴志康,80后创业者携惊叹号而来

nginx伪静态配置和常用rewrite伪静态规则集锦

制作企业网站的一些要点解析

ECSHOP首页商品显示购买次数的实现方法

更多相关阅读请进入《ECSHOP》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...