ASP.NET生成靜態頁面的四種方法

在網上找了幾種比較好的生成靜態頁面的方法,基本上有這幾種原理:
1,第一種,直接獲得服務器生成的html代碼.
圖片

    

#region//生成被請求URL靜態頁面

    public static void getUrltoHtml(string Url, string Path)//Url爲動態頁面地址,Path爲生成的靜態頁面的物理地址及名稱
    {

        try
        {

            System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);

            // Get the response instance.

            System.Net.WebResponse wResp = wReq.GetResponse();

            // Get the response stream.

            System.IO.Stream respStream = wResp.GetResponseStream();

            // Dim reader As StreamReader = New StreamReader(respStream)

            System.IO.StreamReader reader = new System.IO.StreamReader(respStream, System.Text.Encoding.GetEncoding("gb2312"));

            string str = reader.ReadToEnd();

            System.IO.StreamWriter sw = new System.IO.StreamWriter(Path, false, System.Text.Encoding.GetEncoding("gb2312"));

            sw.Write(str);

            sw.Flush();

            sw.Close();

           // System.Web.HttpContext.Current.Response.Write(" ");

        }

        catch (System.Exception ex)
        {

            System.Web.HttpContext.Current.Response.Write(ex);

        }

    }

    #endregion
    protected void Button1_Click(object sender, EventArgs e)
    {
        //生成靜態頁面
        getUrltoHtml("http://localhost:1114/生成靜態/way1.aspx", Request.MapPath(".")+"/html/way1.html");
    }

效果如下,原版照搬了aspx的代碼,但是不足就是一些aspx的功能無法實現了.
圖片
2,第二種方法是從預先做好的模板生成.
圖片

Create.cs

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.IO;

using System.Text;

namespace CreatePage
{

    ///

    /// CreatePage的摘要說明。

    ///

    //原理是利用System.IO中的類讀寫模板文件,然後用Replace替換掉模板中的標籤,寫入靜態html

    // 此類是生成靜態網頁的小程序

    public class Create
    {

        public void CreatePage()
        {

        }
        /// <summary>
        /// 從模板生成靜態頁面
        /// </summary>
        /// <param name="strText">標題</param>
        /// <param name="strContent">內容</param>
        /// <param name="strAuthor">作者</param>
        /// <returns>true成功,false失敗</returns>
        public static bool WriteFile(string strText, string strContent, string strAuthor)
        {

            string path = HttpContext.Current.Server.MapPath(".") + "/html/";//文件輸出目錄

            Encoding code = Encoding.GetEncoding("gb2312");

            // 讀取模板文件

            string temp = HttpContext.Current.Server.MapPath(".")+"/template/test.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 = DateTime.Now.ToString("yyyyMMddHHmmss") + ".html";//靜態文件名

            // 替換內容

            // 這時,模板文件已經讀入到名稱爲str的變量中了

            str = str.Replace("@ShowArticle", strText); //模板頁中的ShowArticle

            str = str.Replace("@biaoti", strText);

            str = str.Replace("@content", strContent);

            str = str.Replace("@author", strAuthor);

            // 寫文件

            try
            {

                sw = new StreamWriter(path + 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;

        }

    }

}



效果如下
圖片
第三種方法,把模板放到代碼中,既快速又方便.
圖片

Create3.cs
using System;

using System.Collections;

using System.Data;

using System.Data.OleDb;

using System.Text;

using System.IO;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;


///

/// 自定義公共函數

///

public class Create3
{

    #region//定義模版頁

    public static string SiteTemplate()
    {

        string str = "";//模版頁html代碼

        str += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
        str += "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>@ShowArticle</title></head>";
        str += "<body><form name=\"form1\" method=\"post\" action=\"way1.aspx\" id=\"form1\"><div><h1>@biaoti</h1><br>作者@author</div><div>@content</div></form></body></html>";
        return str;

    }

    #endregion
    /// <summary>
    /// 根據模板代碼生成靜態頁面
    /// </summary>
    /// <param name="strText">標題</param>
    /// <param name="strContent">內容</param>
    /// <param name="strAuthor">作者</param>
    /// <returns></returns>
    public static bool WriteFile(string strText, string strContent, string strAuthor)
    {

        string path = HttpContext.Current.Server.MapPath(".")+"/html/";//文件輸出目錄

        Encoding code = Encoding.GetEncoding("gb2312");

        StreamWriter sw = null;

        string str = SiteTemplate();//讀取模版頁面html代碼

        string htmlfilename = DateTime.Now.ToString("yyyyMMddHHmmss") + ".html";//靜態文件名

        // 替換內容

        str = str.Replace("@ShowArticle", strText);

        str = str.Replace("@biaoti", strText);

        str = str.Replace("@content", strContent);

        str = str.Replace("@author", strAuthor);

        // 寫文件

        try
        {

            sw = new StreamWriter(path + 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;

    }

}



效果:
圖片

這些都是前三種方法生成的靜態頁面

圖片

第四種方法比較特別,它是讓要生成靜態的頁面繼承我們預先定義的一個類,然後他就會自動生成靜態頁面且訪問動態頁面會自動轉到相應靜態頁面.並且相應鏈接都會轉換爲靜態鏈接.
圖片

index.aspx 紅色標出的是亮點

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Eshop.Web.Index" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>這是第四種生成方法</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>這是第四種生成方法</h1>
        <br />
        
        <html:HtmlPanel ID="hp" runat="server">
            <asp:HyperLink ID="Hy" runat="server" NavigateUrl="~/Index.aspx?page=2">
                   點擊
            </asp:HyperLink>
            <br />
            <a href="~/Index.aspx?page=2" runat="server">Hello</a>
        </html:HtmlPanel>
    </div>
    </form>
</body>
</html>

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Eshop.Web.UI;

namespace Eshop.Web
{
    //繼承HtmlPage類
    public partial class Index : HtmlPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

      1、路徑映射類(UrlMapping),主要對路徑進行拆分、拼接。(關鍵的一步)

      2、過濾流類(FilterStream),主要負責生成靜態頁面。

      3、靜態頁面類(HtmlPage),主要是調用UrlMapping和FilterStream類,

          哪個頁面想靜態化,就繼承這個類。

      4、HtmlHandler類,路徑後綴爲Html的,都由它來處理,與HtmlPage類相似。

      5、HtmlPanel類(控件),頁面帶上這個控件,超鏈接會靜態化。

FilterStream  保存靜態頁面

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO;

namespace Eshop.Web.UI
{
    /// <summary>
    /// 靜態網頁保存
    /// </summary>
    public class FilterStream : Stream
    {
        private Stream respStream = null;
        private Stream fileStream = null;

        public FilterStream(Stream respStream, string filePath)
        {
            if (respStream == null)
                throw new ArgumentNullException("輸出流不能爲空");

            this.respStream = respStream;
            
            try
            {
                this.fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);  //寫入到文件夾中
            }
            catch { }
        }


        public override bool CanRead
        {
            get { return this.respStream.CanRead; }
        }

        public override bool CanSeek
        {
            get { return this.respStream.CanSeek; }
        }

        public override bool CanWrite
        {
            get { return this.respStream.CanWrite; }
        }

        public override void Flush()
        {
            this.respStream.Flush();

            if (this.fileStream != null)
            {
                this.fileStream.Flush();
            }
        }

        public override long Length
        {
            get { return this.respStream.Length; }
        }

        public override long Position
        {
            get
            {
                return this.respStream.Position;
            }
            set
            {
                this.respStream.Position = value;

                if (this.fileStream != null)
                {
                    this.fileStream.Position = value;
                }
            }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return this.respStream.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            if (this.fileStream != null)
            {
                this.fileStream.Seek(offset, origin);
            }

            return this.respStream.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            this.respStream.SetLength(value);

            if (this.fileStream != null)
            {
                this.fileStream.SetLength(value);
            }
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            this.respStream.Write(buffer, offset, count);

            if (this.fileStream != null)
            {
                this.fileStream.Write(buffer, offset, count);
            }
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            this.respStream.Dispose();
            if (this.fileStream != null)
            {
                this.fileStream.Dispose();
            }
        }
    }
}

 HtmlHandler 處理HTML頁面
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO;

namespace Eshop.Web.UI  
{
    /// <summary>
    /// 後綴爲HTML的,都經這裏處理
    /// web.config
    /// <remove verb="*" path="*.HTML"/>
    /// <add verb="*" path="*.HTML" type="Eshop.Web.UI.HtmlHandler,AspxToHtmlDemo"/>
    /// </summary>
    public class HtmlHandler:IHttpHandler
    {
        public bool IsReusable
        {
            get { return false; }
        }

        /// <summary>
        /// 獲取物理路徑,判斷文件夾中有沒有存在這個文件
        /// 不存在的話,就會調用FilterStream類進行創建,並寫入內容
        /// 存在的話,就直接顯示頁面
        /// </summary>
        public void ProcessRequest(HttpContext context)
        {
            HttpRequest request = context.Request;
            HttpResponse response = context.Response;

            string htmlPage = request.RawUrl;
            string htmlFile = context.Server.MapPath(htmlPage);

            if (File.Exists(htmlFile))
            {
                response.WriteFile(htmlFile);
                return;
            }

            //Html 文件不存在
            string aspxPage = UrlMapping.HtmlToAspx(htmlPage);
            response.Redirect(aspxPage);
        }

    }
}

HtmlPage
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO;

namespace Eshop.Web.UI
{
    /// <summary>
    /// 哪個頁面想靜態化,就繼承這個類
    /// </summary>
    public class HtmlPage:Page
    {
        // <summary>
        /// 獲取物理路徑,判斷文件夾中有沒有存在這個文件
        /// 不存在的話,就會調用FilterStream類進行創建,並寫入內容
        /// 存在的話,就直接顯示頁面
        /// </summary>
        public override void ProcessRequest(HttpContext context)
        {
            HttpRequest req = context.Request;
            HttpResponse resp = context.Response;

            string htmlPage = UrlMapping.AspxToHtml(req.RawUrl);
            string htmlFile = context.Server.MapPath(htmlPage);

            if (File.Exists(htmlFile))
            {
                resp.Redirect(htmlPage);
                return;
            }

            // Html 頁面不存在
            resp.Filter = new FilterStream(resp.Filter, htmlFile);
            base.ProcessRequest(context);
        }
    }
}

UrlMapping
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO;

namespace Eshop.Web.UI
{
    /// <summary>
    /// 路徑映射
    /// </summary>
    public static class UrlMapping
    {
        //Aspx 轉換到 Html
        public static string AspxToHtml(string url)
        {
            //判斷路徑是否爲空
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("路徑不能爲空");
            }

            //分割路徑
            string[] temp = url.Split('?');

            if (temp.Length != 1 && temp.Length != 2)
            {
                throw new ArgumentException(String.Format("路徑 {0} 及其參數錯誤", url));
            }

            //獲取路徑後綴
            string ext = Path.GetExtension(temp[0]);    
            if (!(ext.Equals(".aspx", StringComparison.OrdinalIgnoreCase)))
            {
                throw new ArgumentException(String.Format("路徑 {0} 類型必須爲ASPX", url));
            }

            //截取.aspx中前面的內容
            int offset = temp[0].LastIndexOf('.');
            string resource = temp[0].Substring(0, offset);

            //路徑不帶參數時
            if (temp.Length == 1 || string.IsNullOrEmpty(temp[1]))
            {
                return string.Format("{0}.html", resource);    //拼接
            }

            //路徑帶參數時
            return string.Format("{0}___{1}.html", resource, temp[1]); //拼接
        }
        
        //Html 轉換到 Aspx
        public static string HtmlToAspx(string url)
        {
            //判斷路徑是否爲空
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("路徑不能爲空");
            }

            string ext = Path.GetExtension(url);
            if (!(ext.Equals(".html", StringComparison.OrdinalIgnoreCase)))
            {
                throw new ArgumentException(String.Format("路徑 {0} 類型必須爲HTML", url));
            }

            string[] temp = url.Split(new String[] { "___", "." }, StringSplitOptions.RemoveEmptyEntries);
            if (temp.Length == 2)
            {
                return string.Format("{0}.aspx", temp[0]);
            }

            if (temp.Length == 3)
            {
                return String.Format("{0}.aspx?{1}", temp[0], temp[1]);
            }

            throw new ArgumentException(String.Format("資源 {0} 及其參數錯誤", url));
        }
    }
}


圖片
效果
圖片
要實現第四種方法分爲這麼幾個步驟:

1,添加Jiangs_AspxToHtml.dll的引用

2,添加web.config配置節sys.web

   

 <system.web>
      <!--以下爲生成靜態配置節-->
      <globalization requestEncoding="gb2312" responseEncoding="gb2312"/>
      <httpHandlers>
        <remove verb="*" path="*.HTML"/>
        <add verb="*" path="*.HTML" type="Jiangs_AspxToHtml.UI.HtmlHandler"/>
      </httpHandlers>
      <pages>
        <controls>
          <add tagPrefix="html" namespace="Jiangs_AspxToHtml.UI.Controls" assembly="Jiangs_AspxToHtml"/>
        </controls>
      </pages>
      <!--以上爲生成靜態配置節-->

    </system.web>

3,在要靜態化的頁面添加using命名空間

using Jiangs_AspxToHtml.UI;

4,頁面繼承HtmlPage

public partial class JiangsWeb_Default : HtmlPage//繼承此類,生成html 

5,打開頁面試試生成了沒,大功告成!

如果頁面內容有改變需要重新生成,只需要刪除掉已生成的html頁面,它會自動重新生成新的html

6,把Jiangs_AspxToHtml.dll拖到工具欄,有一個HtmlPanel 自定義控件,拖到頁面上,然後把body內容放裏面,裏面的所以連接都會靜態化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章