由於搜索引擎對aspx頁面收錄和html頁面收錄率的差別以及頁面資源佔用問題,我們很多時候需要實現ASPX頁面動態轉靜態。網上也有很多人
討論其實現方法,本人實踐後總結兩種主流方法如下:
第一種方法:
使用模板轉換,步驟如下:
1、建立MyConvert.cs類文件
using System;
//記得添加以下三引用
using System.Text;
using System.Web;
using System.IO;
namespace TesConvert
{
/// <summary>
/// MyConvert 的摘要說明。
/// </summary>
public class MyConvert
{
public MyConvert()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
public bool WriteFile(string strText,string strContent,string strAuthor)
{
string path = HttpContext.Current.Server.MapPath("/TesConvert/news/");//定義html文件存放路徑
Encoding code = Encoding.GetEncoding("gb2312");//定義文字編碼
// 讀取模板文件
string temp = HttpContext.Current.Server.MapPath("/TesConvert/text.html");
StreamReader sr=null;
StreamWriter sw=null;
string str="";
try
{
sr = new StreamReader(temp, code);
str = sr.ReadToEnd(); // 讀取文件
}
catch(Exception exp)
{
HttpContext.Current.Response.Write(exp.Message);
HttpContext.Current.Response.End();
sr.Close();
}
string htmlfilename=path + DateTime.Now.ToString("yyyyMMddHHmmss")+".html";
// 替換內容
// 這時,模板文件已經讀入到名稱爲str的變量中了
str = str.Replace("ShowArticle",strText); //模板頁中的ShowArticle
str = str.Replace("title",strText);
str = str.Replace("content",strContent);
str = str.Replace("author",strAuthor);
// 寫文件
try
{
sw = new StreamWriter(htmlfilename,false,code);
sw.Write(str);
sw.Flush();
}
catch(Exception ex)
{
HttpContext.Current.Response.Write(ex.Message);
HttpContext.Current.Response.End();
}
finally
{
sw.Close();
}
return true;
}
}
}
2、TestNews.aspx文件:
添加三和TextBox分別爲:tbx_Title、tbx_Content、tbx_Author和一個Button:btn_AddNews。
TestNews.aspx.cs文件
private void btn_AddNews_Click(object sender, System.EventArgs e)
{
MyConvert Hover = new MyConvert();
if(Hover.WriteFile(this.txb_Title.Text.ToString(),Server.HtmlDecode(this.txb_Content.Value),this.txb_Author.Text.ToString()))
{
Response.Write("添加成功");
}
else
{
Response.Write("生成HTML出錯!");
}
}
3、添加模板text.html文件
<head>ShowArticle</head>
<body>
title<br>
content<br>
author
</body>
說明:一.news文件夾必須賦予asp.net用戶寫入的權限。這是一個簡單的實現例子,實際項目必須先將數據保存到數據庫下面,在datagird中
調用數據庫下面html文件的URL地址。二.默認情況下,我們是不能向TextBox、TextArea中添加html語法的,必須修改config文件,在
<system.web>下面添加<pages validateRequest="false" />,但是這樣做的話,整個項目中都允許鍵入html標籤了,暫時還不知道其他的方。
缺點:這種方法是在ASP.net在頁面所有內容生成後、輸出內容前對頁面內容進行操作以前曾說過用HttpModule來在Response前更改,不夠靈活
,每行修改response,比較費力。
第二種方法:
重寫AttributeCollection.Render,比較靈活(msdn如是說:“在呈現階段,所有 ASP.NET 移動設備適配器都通過一個稱爲文本編寫器的對象
來編寫它們的輸出。文本編寫器對象是從 TextWriter 基類創建的。”)
可以寫個基類,如:
public class BasePage: System.Web.UI.Page
{
public BasePage()
{
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
string name=Request.Url.AbsolutePath.Substring(1,Request.Url.AbsolutePath.Length-1).Replace("aspx","htm");
string newurl="";
if(name.IndexOf("/")>0)
{
newurl=Server.MapPath("../") + name;
}
else
{
newurl=Server.MapPath("./") + name;
}
MemoryStream ms = new MemoryStream();
StreamWriter sww = new StreamWriter(ms);
StreamWriter swr = new StreamWriter(newurl);
System.Web.UI.HtmlTextWriter htmlw = new HtmlTextWriter(swr);
base.Render(htmlw);
htmlw.Flush();
htmlw.Close();
string strLL = System.Text.Encoding.UTF8.GetString(ms.ToArray());
Response.Write(strLL);
Response.Redirect(Request.Url.AbsoluteUri.Replace("aspx","htm"), true);
}
}
然後在需要生成靜態頁面的頁面中繼承就可以了。
說明:這種辦法是在Asp.net的生成動作完成之後,再進行一次轉換。
缺點:覺得本質上應該還是屬於頻繁post的aspx頁面。
下面是在網絡上搜索到的代碼:
關於在Asp.Net中動態頁面轉靜態頁面的方法網上比較多。結合實際的需求,我在網上找了一些源代碼,並作修改。現在把修改後的代碼以及說明寫一下。
一下是一個頁面轉換的類,該類通過靜態函數Changfile()來實現,動態頁面到靜態頁面的轉換。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.IO;
/**//// <summary>
/// Summary description for HtmlProxy
/// </summary>
public class HtmlProxy
...{
public HtmlProxy()
...{
}
public static bool ChangeFile(int id)
...{
string filename = HttpContext.Current.Server.MapPath("Post_" + id + ".html");
//嘗試讀取已有文件
Stream st = GetFileStream(filename);
//如果文件存在並且讀取成功
if (st != null)
...{
using (st)
...{
StreamToStream(st, HttpContext.Current.Response.OutputStream);
return true;
//Response.End();
}
}
else
...{
StringWriter sw = new StringWriter();
HttpContext.Current.Server.Execute("ForumDetail.aspx?PID=" + id, sw);
string content = sw.ToString();
//寫進文件
try
...{
using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Write))
...{
using (StreamWriter stw = new StreamWriter(fs, HttpContext.Current.Response.ContentEncoding))
...{
stw.Write(content);
}
}
return true;
}
catch ...{ return false; }
}
}
private static Stream GetFileStream(string filename)
...{
try
...{
DateTime dt = File.GetLastWriteTime(filename);
TimeSpan ts = dt - DateTime.Now;
if (ts.TotalHours > 1)
...{
//一小時後過期
return null;
}
return new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch ...{ return null; }
}
static public void StreamToStream(Stream src, Stream dst)
...{
byte[] buf = new byte[4096];
while (true)
...{
int c = src.Read(buf, 0, buf.Length);
if (c == 0)
return;
dst.Write(buf, 0, c);
}
}
}
在頁面文件中,ForURL.aspx的後臺代碼如下:
protected void Page_Load(object sender, EventArgs e)
...{
try
...{
int id = int.Parse(Request.QueryString["PID"]);
if(HtmlProxy.ChangeFile(id))
...{
Response.Redirect("Post_" + id + ".html");
}
else
...{
Response.Redirect("Post.aspx?PID=" + id );
}
}
catch ...{
}
}