ASP.NET 生成静态页面
一、概述
在客户端访问动态页面的时候,有的时候为了提高服务器的性能,可以让其访问生成的静态页面(当然也可用缓存,可这样比较耗资源),这样可以大大的提高访问速度,也能减轻服务器的压力。在 ASP.NET 中,可以通过 Page 类的 Render() 方法来实现。
ASP.NET 中所有的控件都是从 System.Web.UI.Control 类,在 Control 类中定义了三个与呈现有关的方法,分别是 Render(),RenderChildren()和RenderControl().
Control.Render() 方法将服务器控件内容发送到提供的 HtmlTextWriter 对象,此对象编写将在客户端呈现的内容。RenderControl() 方法用于供外部类进行调用,以生成控件,如父控件调用子控件的 Rendercontrol() 方法.在 RenderControl() 方法只是作了是否显示该控件的判断,如果显示则调用控件的被保护方法Render.
Render方法是呈现控件的核心方法,在现实性自定义控件中,我们一般都是通过重写Render方法来呈现控件的,如果控件是一个容器控件,就要重写 RenderChildren() 方法来呈现子控件.这三个方法的关系,可以去看源码。
二、实例:使用 Render() 方法生成静态页面
实例一:使用 RenderControl() 方法
void Page_Load(){
Response.Charset="";
this.EnableViewState =false;
StringWriter stringWriter tw=new StringWriter();
HtmlTextWriter htmlWriter wt =new HtmlTextWriter(stringWriter);
string path=@"c:\test.htm";
StreamWriter sw = File.CreateText(path);
//输出所有信息
this.RenderControl(htmlWriter);
wter.Write(stringWriter.ToString());
//Response.Write(stringWriter.ToString());
sw.Close();
htmlWriter.Close();
stringWriter.Close();
Response.End();
//生成相应文件,然后定向到该文件
Response.Redirect(path);
}
实例二:重写 Render()
首先是基类继承至Page类,一般这种类也叫中间类,将共有的功能在此类中实现,然后让其他类去继承,将达到简化代码的目的。
namespace CommonLib.CreateStaticPage
{
public abstract class StaticPage:Page
{
private StringWriter htmlPage;
public StaticPage()
{ }
protected override void Render(HtmlTextWriter writer)
{
htmlPage = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(htmlPage);
base.Render(htw);
CreatePage(StaticPageFilePath());
ReturnPage(StaticPageFileUrl());
}
protected override void OnInit(EventArgs e)
{
GetOnInit();
if (!IsRefresh(StaticPageFilePath()))
{
ReturnPage(StaticPageFileUrl());
}
base.OnInit(e);
}
private void CreatePage(string filePath)
{
StreamWriter filesw = new StreamWriter(filePath, false, Encoding.GetEncoding("UTF-8"));
filesw.Write(htmlPage);
filesw.Close();
}
private bool IsRefresh(string filepath)
{
if (File.Exists(filepath) && GetRefreshMinute() == 0)
{
return false;
}
else if (File.Exists(filepath) && new FileInfo(filepath).LastWriteTime.AddMinutes(GetRefreshMinute()) >= DateTime.Now)
{
return false;
}
else
{
return true;
}
}
private void ReturnPage(string pageUrl)
{
Response.Redirect(pageUrl);
}
protected abstract string StaticPageFilePath();
protected abstract string StaticPageFileUrl();
protected abstract double GetRefreshMinute();
protected abstract void GetOnInit();
}
}
现在看看子类吧,也就是具体的页面了。
public partial class _Default : CommonLib.CreateStaticPage.StaticPage
{
private string areaid = "";
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text= DateTime.Now.ToLongDateString()+DateTime.Now.ToLongTimeString();
}
// 实现父类中的抽象方法,返回具体存放静态页面的文件路径
protected override string StaticPageFilePath()
{
return "D://Web//CommonLib//test//aa.htm";
}
// 实现父类中的抽象方法,返回访问静态页面时的URL
protected override string StaticPageFileUrl()
{
return "~/aa.htm";
}
// 实现父类中的抽象方法,返回多长时间刷新静态页面,单位是分钟
protected override double GetRefreshMinute()
{
return 10;
}
// 实现父类中的抽象方法,初始化某些资源
protected override void GetOnInit()
{
}
}
经过上面的设置,当我们访问Default.aspx页面时,首先程序会将Default.aspx页面生成aa.htm,并用WEB/aa.heml的虚拟路径映射到此静态页面。并且相隔10分钟之后才会刷新动态页面,这样服务器每隔10分钟才会有一次交互,大大的减轻了服务器的压力哟!
实例三:生成静态化页面
public class StaticFileCachePageBase : System.Web.UI.Page
{
bool IsValidCacheFile = false; //是否为有效的缓存
string CacheFilePath = string.Empty; //缓存文件路径
string CacheFolder = "/Cache/"; //设置缓存文件保存位置
const int CacheSeconds = 3600; //设置缓存保存的时间
string encoding = "gb2312";
void ClearTimeOutFile(string folder)
{
DateTime now = DateTime.Now;
DirectoryInfo di = new DirectoryInfo(folder);
FileInfo[] fis = di.GetFiles();
foreach (FileInfo file in fis)
{
TimeSpan ts = now - file.LastWriteTime;
if (ts.TotalSeconds > CacheSeconds)
{
file.Delete();
}
}
}
protected override void OnPreInit(EventArgs e)
{
string code = Encryption.Escape(Request.RawUrl);
string folder = CacheFolder + code[0] + "/" + code[1] + "/";
CacheFilePath = Server.MapPath(folder + code + ".html");
if (File.Exists(CacheFilePath))
{
TimeSpan ts = DateTime.Now - File.GetLastWriteTime(CacheFilePath);
if (ts.TotalSeconds <= CacheSeconds)
{
IsValidCacheFile = true;
Response.ContentEncoding = System.Text.Encoding.GetEncoding(encoding);
Response.TransmitFile(CacheFilePath);
return;
}
}
ClearTimeOutFile(folder);
base.OnPreInit(e);
}
protected override void Render(HtmlTextWriter writer)
{
if (!IsValidCacheFile)
{
StringWriter sw = new StringWriter();
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(sw);
base.Render(htmlTextWriter);
htmlTextWriter.Flush();
htmlTextWriter.Close();
string pageContent = sw.ToString();
Response.Write(pageContent);
string folder = Path.GetDirectoryName(CacheFilePath);
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
using (var fs = File.Create(CacheFilePath))
{
byte[] data = System.Text.Encoding.GetEncoding(encoding).GetBytes(pageContent);
fs.Write(data, 0, data.Length);
fs.Close();
}
}
}
}
public class Encryption
{
public static string Escape(string content)
{
string base64 = EncodeBase64(content);
string reverseString = ReverseString(base64);
string crossString = EncodeCrossString(reverseString, 3);
return crossString;
}
public static string UnEscape(string content)
{
string decodeCrossString = DecodeCrossString(content, 3);
string reverseString = ReverseString(decodeCrossString);
return DecodeBase64(reverseString);
}
public static string DecodeBase64(string str)
{
try
{
byte[] bytes = Convert.FromBase64String(str);
return Encoding.Default.GetString(bytes);
}
catch
{
return str;
}
}
public static string DecodeCrossString(string str, int bitNum)
{
int num3;
StringBuilder builder = new StringBuilder();
int num = str.Length % bitNum;
int num2 = (str.Length - num) / bitNum;
string str2 = str.Substring(str.Length - num);
string[] strArray = new string[num2];
for (num3 = 0; num3 < num2; num3++)
{
strArray[num3] = str.Substring(num3 * bitNum, bitNum);
}
string str3 = strArray[num2 - 1];
for (num3 = num2 - 1; num3 > 0; num3--)
{
strArray[num3] = strArray[num3 - 1];
}
strArray[0] = str3;
for (num3 = 0; num3 < num2; num3++)
{
strArray[num3] = strArray[num3].Substring(1) + strArray[num3].Substring(0, 1);
builder.Append(strArray[num3]);
}
builder.Append(str2);
return builder.ToString();
}
public static string EncodeBase64(string str)
{
return Convert.ToBase64String(Encoding.Default.GetBytes(str));
}
public static string EncodeCrossString(string str, int bitNum)
{
int num3;
StringBuilder builder = new StringBuilder();
int num = str.Length % bitNum;
int num2 = (str.Length - num) / bitNum;
string str2 = str.Substring(str.Length - num);
string[] strArray = new string[num2];
for (num3 = 0; num3 < num2; num3++)
{
strArray[num3] = str.Substring(num3 * bitNum, bitNum);
}
string str3 = strArray[0];
for (num3 = 0; num3 < (num2 - 1); num3++)
{
strArray[num3] = strArray[num3 + 1];
}
strArray[num2 - 1] = str3;
for (num3 = 0; num3 < num2; num3++)
{
strArray[num3] = strArray[num3].Substring(bitNum - 1) + strArray[num3].Substring(0, bitNum - 1);
builder.Append(strArray[num3]);
}
builder.Append(str2);
return builder.ToString();
}
public static string ReverseString(string str)
{
StringBuilder builder = new StringBuilder();
for (int i = str.Length - 1; i >= 0; i--)
{
builder.Append(str[i]);
}
return builder.ToString();
}
}