由于这段时间比较轻松,于是想到很多的企业网站,新闻网站需要将页面静态化,于是写了个封装类来实现静态文件的生成,思路比较简单,但未完善,网友可根据自己的思路将此类扩展,运用了简单工厂模式(本来刚开始看设计模式,是个好书),好了,废话不多说,先来看看静态类的父类:StaticBase(抽象类)
1 public abstract class StaticBase : IDisposable 2 { 3 /// <summary> 4 /// 默认编码方式 5 /// </summary> 6 PRotected Encoding code = Encoding.GetEncoding("utf-8"); 7 /// <summary> 8 /// 写入页面数据流 9 /// </summary>10 protected StreamWriter sw = null;11 /// <summary>12 /// 读取页面数据流13 /// </summary>14 protected StreamReader sr = null;15 /// <summary>16 /// 生成的静态页面保存文件夹路径17 /// </summary>18 protected string SavePath = "/Default/";19 /// <summary>20 /// 模板页面的文件夹路径21 /// </summary>22 protected string PagePath = "/Master/";23 public abstract bool Osucess { set; get; }24 public abstract string Errorstring { set; get; }25 /// <summary>26 /// 具体生成静态方法27 /// </summary>28 protected abstract bool WriteFile();29 /// <summary>30 /// 不同模块的文件名称31 /// </summary>32 protected Dictionary<FlagsFileName, string> FileName33 {34 get35 {36 return new Dictionary<FlagsFileName, string>37 {38 {FlagsFileName.News,"article"},39 {FlagsFileName.head,"head"},40 {FlagsFileName.foot,"foot"},41 };42 }43 }44 // http://www.VEVb.com/roucheng/45 #region IDisposable 成员46 47 public void Dispose()48 {49 sw.Dispose();50 sr.Dispose();51 }52 53 #endregion54 }55 #region 对应的页面名称56 /// <summary>57 /// 对应的页面名称58 /// </summary>59 public enum FlagsFileName : byte60 {61 /// <summary>62 /// 新闻63 /// </summary>64 [Description("新闻")]65 News = 0,66 /// <summary>67 /// 头部68 /// </summary>69 [Description("头部")]70 head=1,71 /// <summary>72 /// 脚部73 /// </summary>74 [Description("脚部")]75 foot=2,76 }
最后的一个枚举用于定义不同位置或不同类别的静态页所对应的子类
,接下来看看其中一个子类的实现(该子类是用于所有单页,如数据库中有100条新闻记录,那相应的生成100个新闻html页面,格式用模板定义的格式确定)
首先模板文件时静态的html页面,其中所有的需要从数据库中替换的字段用一对$包含,如数据库中的新闻标题字段为titles,则模板页中相应的标题位置用$titles$表示,页面如下
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 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>$Titles$</title> 6 </script> 7 </head> 8 <body> 9 <div id="wrap">10 $head$11 <!--hd end-->12 <div class="clear"></div>13 <div id="wp">14 <table border="0" cellpadding="0" cellspacing="0" width="980">15 <tr>16 <td rowspan="3" valign="top" id="main_box" class="index_box2">17 <div class="subtitle subtitle4"></div>18 <div class="article">19 <div class="title">$Titles$</div>20 $Contents_tw$21 </div> 22 23 24 </td>25 <td width="48" height="44" class="ri_top"> </td>26 </tr>27 <tr>28 <td class="ri_mid" id="mid_box"> </td>29 </tr>30 <tr>31 <td height="44" class="ri_bottom"> </td>32 </tr>33 </table>34 </div>35 <!--wp end-->36 </div>37 <!--wrap end-->38 39 $foot$40 <!--ft end-->41 </body>42 </html>
http://www.VEVb.com/roucheng/
到这里知道个大概了吧,接下来就是这中页面类型的子类实现,我将它的名称定义为ViewPage,因为所有可以单独显示的页面都可以用这个子类,代码如下
1 public class ViewPage : StaticBase 2 { 3 /// <summary> 4 /// 是否操作成功 5 /// </summary> 6 private bool o_sucess = true; 7 /// <summary> 8 /// 错误信息 9 /// </summary> 10 private string errorstring = string.Empty; 11 /// <summary> 12 /// 模板文件名称 13 /// </summary> 14 private string masterhtml; 15 /// <summary> 16 /// 数据源 17 /// </summary> 18 private IEnumerable<DataRow> rowlist; 19 /// <summary> 20 /// 模块类别 21 /// </summary> 22 private FlagsFileName fname; 23 /// <summary> 24 /// 指定命名文件的标志列(从数据库中的字段) 25 /// </summary> 26 private string thekey; 27 public override bool Osucess 28 { 29 get { return o_sucess; } 30 set { o_sucess = value; } 31 } 32 public override string Errorstring 33 { 34 get { return errorstring; } 35 set { errorstring = value; } 36 } 37 /// <summary> 38 /// 构造器静态生成对象 39 /// </summary> 40 /// <param name="rlist">需要生成静态文件的数据源</param> 41 /// <param name="fn">文件类别枚举</param> 42 /// <param name="myid">此字段为数据库表中字段,由该字段指定生成的文件名字标志 </param> 43 public ViewPage(DataRow[] rlist,FlagsFileName fn,string myid) 44 { 45 this.thekey = myid; 46 this.fname = fn; 47 this.rowlist = rlist; 48 this.masterhtml = FileName[fn] + ".html"; 49 WriteFile(); 50 } 51 52 protected override bool WriteFile() 53 { 54 string str = ""; 55 try//从指定模板文件中读取html代码 56 { 57 sr = new StreamReader(HttpContext.Current.Server.MapPath(PagePath + this.masterhtml), code); 58 str = sr.ReadToEnd(); 59 } 60 catch (Exception ex)//异常则指定返回的错误信息 61 { 62 sr.Close(); 63 sr.Dispose(); 64 this.o_sucess = false; 65 this.errorstring = ex.Message; 66 return this.o_sucess; 67 } 68 sr.Close(); 69 sr.Dispose(); 70 List<FlagsFileName> fn = new List<FlagsFileName>(); 71 fn.Add(FlagsFileName.head); 72 fn.Add(FlagsFileName.foot); 73 PointPage pg = new PointPage(fn, str); 74 //要保存的文件名称 75 string htmlfilename = string.Empty; 76 string changestring = "";//要更改的字符串 77 foreach (DataRow row in this.rowlist)//遍历数据源数组中的每个数据表 78 { 79 string newString = str; 80 try 81 { 82 htmlfilename = FileName[fname] + "_" + row[thekey].ToString() + ".html";//给文件命名 83 foreach (DataColumn c in row.Table.Columns)//遍历单个数据表的列名 84 { 85 changestring = "$" + c.ColumnName + "$"; 86 newString = newString.Replace(changestring, row[c].ToString()); 87 } 88 sw = new StreamWriter(HttpContext.Current.Server.MapPath(SavePath + htmlfilename), false, code); 89 sw.Write(newString); 90 sw.Flush(); 91 } 92 catch (Exception ex) 93 { 94 this.o_sucess = false; 95 this.errorstring = ex.Message; 96 return this.o_sucess; 97 } 98 99 }100 sw.Dispose();101 sw.Close();102 return true;103 }104 }
好,到这里实现了底层的思路设计,那调用就很简单了,某个aspx页面,一个按钮button,一个点击事件Button_Click,点击事件内需要做的就是声明一个基类StaticBase,将它实例化成一个子类ViewPage,传递的参数为一个数据项集合,DataRow[]为从数据表中读取的集合,包含需要替换的字段,如select titles,c
新闻热点
疑难解答