[C#/ASP.net WebForm] 把動態網頁轉成靜態網頁

[C#/ASP.net WebForm] 把動態網頁轉成靜態網頁

為了避免動態網頁存取資料庫導致網頁速度降低(通常指首頁的情況)

這時候可以寫支Console程式再利用Windows作業系統的排程,定期執行該Console,把動態網頁Render出來的Html另外儲存一份.html靜態檔案

而下次瀏覽器連結到首頁時,就直接連結該.html靜態檔案(可以從IIS設定”預設文件”,把index.html移到最上面)

如此可以增加網頁的載入速度

 

Console檔程式


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Configuration;
namespace ConvertASPXtoHTML
{
    class Program
    {
        //要另存成html的aspx
        static string targetASPX = ConfigurationManager.AppSettings["targetASPX"];
        //要存檔的路徑
        static string savePath = ConfigurationManager.AppSettings["savePath"];
        static void Main(string[] args)
        {

            WebClient wc = new WebClient();
            //目前網頁多半是UTF8編碼
            wc.Encoding = System.Text.Encoding.UTF8;
            //下載html字串
            string html = wc.DownloadString(targetASPX);


            using (FileStream fs = new FileStream(savePath, System.IO.FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                StreamWriter sw = new StreamWriter(fs);
                //輸出html字串
                sw.Write(html);
                sw.Close();
                fs.Close();
            
            }
           

        }
    }
}

App.config


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!--要另存成html的aspx-->
    <add key="targetASPX" value="http://web.xxx.gov.tw/Internet/index/index.aspx"/>
    <!--要存檔的路徑-->
    <add key="savePath" value="D:\web\index.html" />
  </appSettings>
</configuration>

 

 

一般網頁的圖檔(src)或超連結路徑都會有相對路徑,所以Html要存檔的話,最好和index.aspx在同一個目錄下

目前玩了下來

如果原本的.aspx中有使用到UpdatePanel的話,產生出來的html裡UpdatePanel的地方會沒有反應,有這個缺點

現成懶人包:ConvertASPXtoHTML.rar

相關討論:根据ASPX网页中输入的内容,生成静态的HTML页面?

 

2012.3.10 追記

底下有人發問,提醒了我此文章還有後續

本人自己開發的網站,也是遇到首頁會隨著使用者是否已登入,畫面顯示不同的歡迎訊息和登入、登出鍵

面對這樣的需求可以使用Ajax,向Server端程式Request,讀取或設定Session即可

先看該Server端程式:

歡迎訊息


<%@ WebHandler Language="C#" Class="LoginStatus" %>

using System;
using System.Web;
using System.Web.SessionState;
//執行登入
public class LoginStatus : IHttpHandler,IRequiresSessionState {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        if (context.Session["memberInfo"]!=null)
        {
            //假設從DB撈出會員的姓名
            string name = "王大明";
            //要回傳給前端的字串
            string result = "親愛的"+name+"歡迎您使用本系統";
            context.Response.Write(result);
        }
        else
        {
            context.Response.Write("您尚未登入");
        }
        
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

執行登入或登出


<%@ WebHandler Language="C#" Class="toLogin" %>

using System;
using System.Web;
using System.Web.SessionState;

//執行登入或登出動作
public class toLogin : IHttpHandler,IRequiresSessionState
{
    
    public void ProcessRequest (HttpContext context) {

        if (!string.IsNullOrEmpty(context.Request.Form["goLogin"]))//防呆
        {
            string goLogin = context.Request.Form["goLogin"];
             
            if (goLogin=="1")
            {//執行登入
                context.Session["memberInfo"] = true;//不一定要塞true,這裡可以依自己需求塞物件也可以
                 
            }
            else
            {//執行登出
                context.Session["memberInfo"] = null;
                
            }
        }
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

前端程式寫法(.aspx)


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"
    Debug="true" %>

<!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 id="Head1" runat="server">
    <title></title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(init);

        function init() {

            //每次畫面載入時,顯示登入or登出狀態訊息
            showLoginStatus();
            //註冊「登入or登出鍵」click時要做的事
            $("input#toLoginOrLogOut").click(function () {

                var value = $(this).val();//取得button鍵的value文字

                var goLogin = 1; //預設要執行登入
                if (value == "登出") {
                    goLogin = 0;
                }

                //執行登入或登出動作
                $.ajax({
                    url: "toLogin.ashx",
                    type: "post",
                    asnyc: false,
                    data: { goLogin: goLogin },
                    success: function (htmlVal) {

                        if (value == "登入") {
                            $("input#toLoginOrLogOut").val("登出");
                        } else {
                            $("input#toLoginOrLogOut").val("登入");
                        }
                        //顯示登入登出狀態
                        showLoginStatus();
                    },
                    error: function (e) {//顯示錯誤訊息
                        alert(e.responseText);
                    }
                });

            });


        }
        //顯示登入登出狀態
        function showLoginStatus() {

            $.ajax({
                url: "LoginStatus.ashx",
                type: "post",
                asnyc: false,
                data: {},
                success: function (htmlVal) {
                    $("div#loginStatus").html(htmlVal);

                }

            });
        }
    </script>
 
</head>
<body >
    <form id="form1" runat="server"   >
     <!--顯示登入or登出狀態訊息-->
    <div id="loginStatus">
    </div>

    <!--登入or登出鍵-->
    <input id="toLoginOrLogOut" value="登入" type="button" />
     
    </form>
</body>
</html>

來看執行結果,一樣可以先使用Console程式把該.aspx轉成Html檔

image

點選「登入」鈕

image

再點選「登出」鈕把Session設為null的結果

image

最近都在調網站效能,目前要把撈資料庫的連動下拉選單改為撈XML檔方式,再寫支Console檔利用Windows排程,固定一段時間從DB轉出XML檔去覆蓋原始檔

試了一下,連動下拉選單真的有變快,等明後天周末有空再貼上來