Peter's Gekko

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
How to freeze a dynamic aspx page into a static html page (on the server).

Take this scenario: On a website a visitor fills in a form after which the form is to be filed as a static html page. You might have several reasons for wanting to do that, one of them are search engines. Getting it done in asp.net took me more effort than I had originally expected. Let me share what I have found to be working.

The easy way to catch the html rendered by asp.net is to save a page in the client browser. To catch it on the server you have to hook into the (html) rendering process. There is no Page.OnRender event but the Page class does have a Render method. The method has a protected visibility, you cannot  invoke it form your code. The Render method is invoked when asp.net renders the page to the output, to hook in you override the method. The Render method has a parameter of type HtnlTextWriter, the default implementation of the overriden Render method is invoking Base.Render passing it the HtmlTextWriter object.

protected override void Render(HtmlTextWriter writer)
{
   // Default behavior
  
base.Render(writer);
}

This gives a place to hook in an own textwriter where asp,net can render the html into. The constructor of the HTMLtextwriter class has a protected visibility. Passing an own htmltextwriter requires specializing the frameworks's HTMLtextwriter class. The constructor of the base class requires a stringwriter. A wrapper class to house both custom HTMLtextwriter and stringwriter:

internal class MyHtmlFileCreator
{
   private StringWriter html;
   private MyHtmlTextWriter htmlWriter;

   // override the HtmlTextWriter to reach the constructor
   // the constructor in the base class is protected 
   class MyHtmlTextWriter : HtmlTextWriter
   {
      internal MyHtmlTextWriter(TextWriter tw): base(tw){}
   }

   // publish the HTMLwriter
   internal HtmlTextWriter RenderHere
   {
      get {return htmlWriter;}
   }

   // constructor initializes stringwriter and htmlwriter based on that
   // initialize Url 
   internal MyHtmlFileCreator()
   {
      html = new StringWriter();
      htmlWriter = new MyHtmlTextWriter(html);
      newUrl = Context.Request.Url.AbsolutePath.ToString();
      newUrl = newUrl.Replace(".aspx",".htm");
   }

   internal void WriteHTMLFile(string virtualFileName)
   {
      // Stringreader reads output rendered by asp.net
      // Stringwriter writes html output file
      StringReader sr = new StringReader(html.ToString());
      StringWriter sw = new StringWriter();

      // Read from input
      string htmlLine = sr.ReadLine();
      while (htmlLine != null)
      {
      // Filter out ASp.net specific tags
      if (! ((htmlLine.IndexOf("<form") > 0) ||
            (htmlLine.IndexOf("__VIEWSTATE") > 0) ||
            (htmlLine.IndexOf("</form>") > 0) ))
         {sw.WriteLine(htmlLine);}

      htmlLine = sr.ReadLine();
      }

      // Write contents stringwriter to html file
     
StreamWriter fs = new StreamWriter(virtualFileName);
      fs.Write(sw.ToString());
       fs.Close();
   }

}

A MyHtmlFileCreator object has a place asp.net can render to and it has a method to write the contents of the stringwriter (inside the htmlwriter) to file. I use the MyHtmlFileCreator in a page base class. The page hooks in the render event. When the freeze flag is set the html is rendered to a file and the application is redirected to the html file just created.

public class FreezablePage : System.Web.UI.Page
{
   internal class MyHtmlFileCreator{}

   // When Asp.Net renders the page the Page.Render method is invoked
   // Override the method to hook in

   protected override void Render(HtmlTextWriter writer)
   {
      if (freeze)
      {
         MyHtmlFileCreator htmlFile = new MyHtmlFileCreator();
         // Let Asp.net render the output, catch it in the file creator
         base.Render(htmlFile.RenderHere);
         // Write new html file
         htmlFile.WriteHTMLFile(Server.MapPath(NewUrl));
         // Redirect
         Response.Redirect(NewUrl, true);
      }
   else
   {
      // Default behavior
      base.Render(writer);
   }

   }

   // Flag render event
   protected void Freeze()
  {
      freeze = true;
   }

   protected void Freeze(string toUrl)
   {
      freeze = true;
      NewUrl = toUrl;
   }

   private bool freeze = false;

   private string newUrl;

   internal string NewUrl
   {
      get
      {
         return newUrl;
      }
      set
      {
          newUrl = value;
      }

   }

   }

}

Use this on your page like this :

public class _Default : Gekko.Web.UI.FreezablePage
{
    private void Button1_Click(object sender, System.EventArgs e)
   {
      Freeze(string.Format(@"Statisch/{0}.htm", TextBox1.Text));
   }
}

You will see that the resulting page has lost its form knocking out al buttons. There are no more postback possible. And the viewstate is also cut away. To process any file asp.net might produce will require more filtering. You can do quite flexible things treating the input as xml. Which requires some cutting and pasting, an html document is not always well-formed.

BTW Firefox was a lovely sidekick. The way it  displays the html source of a page..mmm:>

Peter


Posted 11-01-2004 7:40 PM by pvanooijen
Filed under:

[Advertisement]

Comments

Scott Galloway wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 11-01-2004 4:05 PM
You could also use SGML Reader (http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=B90FDDCE-E60D-43F8-A5C4-C3BD760564BC) to automagically convert the HTML. I use this for an input filter (so stripping out specific tags / attributes from user-input HTML using XSLT) and it works pretty well.
Nawaz wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 01-06-2005 10:14 AM
any chance of further explantion for beginners or source code post?

Many thanks
Peter van Ooijen wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 01-07-2005 3:23 AM
Nawaz, all sourcecode is here. You have to know the basics of OOP in .NET to work with it. Including all that would result in a complete book.

Is there any specific detail which puzzles you ?
Nawaz wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 02-20-2005 3:24 PM
Peter, thanks for caring. I am an OO newbie and so was really hoping for a downloadable visual studio project - as I am left wondering where to put things... and how to get the project structure in place... will do some homework instead. thank you
Martyn wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 07-18-2005 3:09 PM
Cheers, this was useful post, it has saved me a bit of time figuring out how to do this. I am going to use it to save the output of individual web controls.
maxmanus wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 09-22-2005 6:44 AM
I don't understand this:

"The constructor of the HTMLtextwriter class has a protected visibility. Passing an own htmltextwriter requires specializing the frameworks's HTMLtextwriter class."

The framework HtmlTextWriter's constructor is indeed public:

public HtmlTextWriter ( System.IO.TextWriter writer )
pvanooijen wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 09-22-2005 8:33 AM
The overloaded constructor, which needs a textwriter as parameter, is indeed public. The default parameterless constructor, needed here, is protected.
雨花中的小皮鞋 wrote 怎样利用aps。net动态生成html文件,包括首页?(摘自CSDN)
on 03-02-2006 9:01 PM
怎样利用aps。net动态生成html文件,包括首页?(摘自CSDN)
why wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 03-25-2006 10:09 PM
Why do you not use urlwrite to generate html from asp.net dynamicly ?
pvanooijen wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 03-27-2006 2:58 AM
Because I want static content. Based on data which might no longer be available later on.
Johniewalker wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 09-07-2006 4:23 AM

hi,pvanooijen,I am newcomer in asp.net.If possible,plz send sourcecode  to theconfessions@hotmail.com,many Tks!

pvanooijen wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 09-07-2006 1:28 PM

Johnie, all sourcecode you need is present in this post. Check your asp.net training material how to include it in your own project.

不是专家 wrote 将动态aspx页面转换成为静态html页面的几种方法
on 12-08-2006 2:48 AM

将动态aspx页面转换成为静态html页面的几种方法

nhpyliner wrote 将动态aspx页面转换成为静态html页面的几种方法
on 12-08-2006 3:46 AM

将动态aspx页面转换成为静态html页面的几种方法

sam wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 12-16-2006 8:20 AM

I am newcomer in asp.net  from china,you arcticle is great,but  i can't run you program well, could you give me complete example that can run,thanks a lot!

my email: smhy8187@126.com

pvanooijen wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 12-18-2006 2:15 AM

Greate to see the intereset from your part of the globe. I have no more material at hand than this. I take your word it could be to quick for newcomers. One day I'll write a more elaborate story on this.

Allan Rosner wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 05-06-2007 9:23 AM

Peter,

Thanks for the great post.  I am using your MyHtmlFileCreator class In an ASP.NET 2.0 application.  Everything works fine except when I execute the last Response.Redirect in the Render event, I get the error, "Cannot redirect after HTTP headers have been sent.".  Is there any workaround?

Thanks in advance,

Al

pvanooijen wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 05-14-2007 5:04 AM

You, or your code, have already written something else to the response. The Response object has a ClearHeaders and ClearContent method. Try issuing that before redirecting.

goodbus wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 08-12-2007 6:41 AM

great

yorkane wrote 如何将ASPX 转换为静态文件。
on 09-18-2007 12:42 PM

如何将ASPX 转换为静态文件。这里将介绍实现方法,并提供一个完整的Web网站示例

天山寒雪 wrote [转] ASP.NET 动态页面静态化
on 11-22-2007 9:24 AM

.

缘于2046 wrote [转] 动态页面静态化
on 11-22-2007 10:36 AM

.

huangzhen wrote re: How to freeze a dynamic aspx page into a static html page (on the server).
on 12-18-2008 8:58 PM

I am newcomer in asp.net  from china,you arcticle is great,but  i can't run you program well, could you give me complete example that can run,thanks a lot!

E-mail:huangzhen_2008@163.com

Add a Comment

(required)  
(optional)
(required)  
Remember Me?