How to generate static html pages and redirect them with urlrewrite

Even though most of people are using database and programming languages to structure their websites,
but often website performance is limited by the cpu and memory usage of the virtual host, people are intend
to create static html file to reduce cpu usage, but static html file are hard to maintain, so what`s the best
way to keep the exsiting file structure but also create static html to increase the performance? We will show you how.


 
file structure
File Structure

The picture on the left side is our file structure of website,
"Static" is the directory where static html will be stored.
"HtmlStaticOutput.aspx" is the program we will discuss later,
our goal is to fetch content from Page1~3 and save them as 
static html file.

Don`t forget to add IIS_IUSRS permission in "Static" folder,
or the error will occur.

Firstable, you need to create an array to store url, and of course you need to know the url of the
pages you want to make static html file, you can either manully hard code it in program or if you 
have url stored in database, you can just get it from database.

In here we create a string array, and put the url in this array.
string[] Urls = new string[] {  
        "http://192.168.1.1/Page1.aspx", "http://192.168.1.1/Page2.aspx",
        "http://192.168.1.1/Page3.aspx"
    };
And next we use WebClient class to retrieve content from the pages.
void DoFetch(string url)
{
    string SavePath = "Static";
    string FileName = Path.GetFileName(url).Replace("aspx", "html");
    string result;

    WebClient wc;

    try
    {
        using (wc = new WebClient())
        {
            using (Stream s = wc.OpenRead(url))
            {
                using (StreamReader sr = new StreamReader(s))
                {
                    result = sr.ReadToEnd();
                    sr.Close();
                }
            }
        }

        string PhysicalPath = Server.MapPath(SavePath);
        PhysicalPath = Path.Combine(PhysicalPath, FileName);

        using (StreamWriter sw = new StreamWriter(PhysicalPath, false, Encoding.UTF8))
        {
            sw.WriteLine(result);
            sw.Close();
        }
    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
    }
}

We create SavePath variable, this is the directory where static html files will be stored,
then we use WebClient.OpenRead to retrieve content and then use StreamWriter to save as html
in the "Static" directory. 

Now we have satic html files we need, the next thing is to keep the existing file structure
and let users can browse static html file at the same time, so we use URL Rewrite module in
IIS to archive this, when you finished put it in Web.config.
<rewrite>
    <rules>
        <rule name="Redirect To Static HTML" stopProcessing="true">
            <match url="^(.*).html$" />            
            <action type="Rewrite" url="static/{R:1}.html" />
        </rule>
    </rules>
</rewrite>

We take all requests for .html redirect them to the Static directory, this way, not only you can 
keep the existing file structure but also you can still browse website by requesting .aspx.

Ex: http://192.168.1.1/Page1.aspx and http://192.168.1.1/Page1.html
no matter you request for .aspx or .html, both can see the same content.

HtmlStaticOutput.aspx.cs Expand
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Net;
using System.IO;

public partial class HtmlStaticOutput : System.Web.UI.Page
{
    string[] Urls = new string[] {  
        "http://192.168.1.1/Page1.aspx",
        "http://192.168.1.1/Page2.aspx",
        "http://192.168.1.1/Page3.aspx"
    };

    protected void Page_Load(object sender, EventArgs e)
    {
        for (int i = 0; i < 1; i++)
        {
            DoFetch(Urls[i]);
        }
    }

    void DoFetch(string url)
    {
        string SavePath = "Static";
        string FileName = Path.GetFileName(url).Replace("aspx", "html");
        string result;

        WebClient wc;

        try
        {
            using (wc = new WebClient())
            {
                using (Stream s = wc.OpenRead(url))
                {
                    using (StreamReader sr = new StreamReader(s))
                    {
                        result = sr.ReadToEnd();
                        sr.Close();
                    }
                }
            }

            string PhysicalPath = Server.MapPath(SavePath);
            PhysicalPath = Path.Combine(PhysicalPath, FileName);

            using (StreamWriter sw = new StreamWriter(PhysicalPath, false, Encoding.UTF8))
            {
                sw.WriteLine(result);
                sw.Close();
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
        }
    }
}
comments powered by Disqus