Introduction
In the ASP.NET version 3.5 output cache providers customization is not supported, so for some cases it needs to create specific mechanizm for saving cached data to the file system (hard drive). In this article I'll demonstrate how to cache the entire page into the file system using HTTPModule
and Render
method of the web page.
Background
The new version of the ASP.NET, starting from 4.0 allows customize cache providers, to save cached data in file system. Custom cache provider can be specified using ProviderName attribute of the @OutputCache tag. But in the previous versions of the ASP.NET this could not be easily configured. Recently, I had a need to cache web page content on file system for web application based on 3.5 framework version. This was achieved by creating custom HTTP module and overriding Render method of the page.
Using the code
For saving catched data to the file system it needs to create .Net Module and register it in the web.config file.
public class CustomOutputCacheModule : IHttpModule
{ }
In the Module class, AuthenticateRequest
event can be used to validate user info and address and return cached page content. Subscription can be made in the Init
event handler:
public void Init(HttpApplication application)
{
application.AuthenticateRequest += (new EventHandler(this.Application_AuthenticateRequest));
}
AuthenticateRequest
event was selected in order to be able customize cached page per user.
private void Application_AuthenticateRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication) source;
HttpContext context = application.Context;
string filePath = context.Request.FilePath;
if (context.User != null && context.Request.RequestType == "GET" && .... )
{
string cacheFileKey = string cachedPageContent = File.ReadAllText("C:\pagechache.dat");
if (!string.IsNullOrEmpty(pageContent))
{
context.Response.Write(cachedPageContent);
application.CompleteRequest();
}
}
}
After this is done, it needs to register this Module in web.config file, in both places
<httpModules><add name="CustomCacheHttpModule" type="CustomOutputCacheModule ..... / namespace and library name / "/>
and
<system.webServer><modules><add name="CustomCacheHttpModule" preCondition="managedHandler" type="CustomOutputCacheModule ..... / namespace and library name / "/>
In the target web page, following code should be used to catch generated content and save it to file system. Saved file data should be used in the Module. IMPORTANT! The w3wc IIS process has to have enough privileges for writing to the file system, otherwise access denied exception is thrown.
protected override void Render(HtmlTextWriter writer)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter hWriter = new HtmlTextWriter(sw);
base.Render(hWriter);
string cachedPageResult = sb.ToString();
File.Save("C:\pagechache.dat", cachedPageResult)
writer.Write(cachedPageResult);
}
Points of Interest
In the recent versions of .Net framework, starting from ASP.NET 4.0 it is possible to define custom output cache provider and save cached data to the file system or elsewhere. Here are some examples:
http://www.4guysfromrolla.com/articles/061610-1.aspx
http://www.drdobbs.com/windows/creating-a-custom-output-cache-provider/232601001
But these solutions are not applicable to the previous versions, so the easiest way is to create Module, that's described in the article above.
History