Home » ASP.NET » Virtual Files using HttpContext.RewritePath()

Virtual Files using HttpContext.RewritePath()

One of the cool new tricks we are able to perform in ASP.NET that we were not able to use in ASP is the ability to have ASP.NET redirect file requests in the same way that mod_rewrite does under the Apache webserver.

For example, we could have the browser ask for an image file that doesn’t exist on the file system and have ASP.NET serve up the file from the database. Or, if we wanted to protect some files, we could put them in a directory that was hard to guess and have ASP.NET load that file for us when the browser requested the file from what looked like a normal location.

The magic that makes all this work is the 404 error handler, the Application_BeginRequest() event handler, and the HttpContext.RewritePath() method.

So, the first thing we need to do is open up our Global.asax file and create an event handler for BeginRequest(). This event is the first thing that will get called when a request is made to ASP.NET.

protected void Application_BeginRequest(Object sender, EventArgs e)
{
}

Second, we will want to create a 404 error handler in IIS. You may have done this in prior applications, like ASP, to tell the user that a page no longer existed or to redirect the browser to a page whose name had changed. We are going to use it to force the Application _BeginRequest() method to fire even when a static file isn’t found. All you need to do is tell IIS that an ASPX file is the 404 handler. It doesn’t matter what you call it and it doesn’t matter if the file even exists on the server. The only thing that does matter is that you SAY that the file exists in the application directory that you’ve created your web application in.

Now that you’ve specified your 404 handler, any file that can’t be found on the server will automatically fire the Application_BeginRequest event handler. So the next thing we need to do is add code in this method to check for the 404 condition.

if (Request.ServerVariables["QUERY_STRING"].Length > 4 &&
Request.ServerVariables["QUERY_STRING"].StartsWith("404;"))

{

Context.Trace.Write("QueryString > 1");

String queryString =

Request.ServerVariables["QUERY_STRING"].Substring(4).ToLower();

// strip off the http:// or https://


queryString = queryString.Replace("http://", "")

.Replace("https://", "");

// strip of the host section


queryString = queryString.Substring(queryString.IndexOf("/") + 1);

string applicationDirectory = Request.ApplicationPath;

if (applicationDirectory.StartsWith("/"))

applicationDirectory = applicationDirectory.Substring(1);

queryString = queryString.Substring(applicationDirectory.Length);

if (queryString.ToCharArray()[0] != '/')

queryString = "/" + queryString;

}

 

Remember from your ASP days, when a 404 error handler is called, the query string starts with “404;”, so this code is checking for that and stripping it out. Then it looks for the file that was being requested and strips off everything but the file location. This code will work if your application is in a subdirectory or if it is in the root of your domain, leaving you with an application relative reference to the file the browser was looking for.

Once you have that, you can format the request to the real location and call

HttpContext.Current.RewritePath(newLocation)

Passing in the call to an ASPX file that will actually return the correct information.

In the code that I originally wrote, this was looking for our virtual images directory and passed the call on to our virtual images handler which pulls the image out of the database.

if (queryString.StartsWith(imagesDirectory))
{

HttpContext.Current.RewritePath("VirtualImage.aspx?"+queryString);

return;

}

And, just to preempt any comments about performance, the VirtualImage.aspx file caches the results so that we are not constantly pulling the image from the database.

Here’s the full handler:

protected void Application_BeginRequest(Object sender, EventArgs e)
{

if (Request.ServerVariables["QUERY_STRING"].Length > 4 &&

Request.ServerVariables["QUERY_STRING"].StartsWith("404;"))

{

Context.Trace.Write("QueryString > 1");

String queryString =

Request.ServerVariables["QUERY_STRING"].Substring(4).ToLower();

// strip off the http:// or https://


queryString = queryString.Replace("http://", "")

.Replace("https://", "");

// strip of the host section


queryString = queryString.Substring(queryString.IndexOf("/") + 1);

string applicationDirectory = Request.ApplicationPath;

if (applicationDirectory.StartsWith("/"))

applicationDirectory = applicationDirectory.Substring(1);

queryString = queryString.Substring(applicationDirectory.Length);

if (queryString.ToCharArray()[0] != '/')

queryString = "/" + queryString;

string imagesDirectory =

ConfigurationManager.AppSettings["VirtualImageDirectory"];

if (queryString.StartsWith(imagesDirectory))

{

HttpContext.Current.

RewritePath("VirtualImage.aspx?"+queryString);

return;

}

if (queryString.Contains("app_themes"))

HttpContext.Current.

RewritePath("ResolveRelativeReference.aspx?" +

queryString);

}

}

 

 

Other post in ASP.NET

Related Post

  • ASP.NET Dynamic ValidatorASP.NET Dynamic Validator One of the controls that was added to ASP.NET 3.5 in the SP1 release was the Dynamic Validator control.I completely missed it.What it does is pretty cool.  But it doesn’t […]
  • ASP.NET Application_Error Detecting 404’sASP.NET Application_Error Detecting 404’s For many of you, this is going to be a "Duh!" kind of post.  But while working on this today, I found so many people asking this question and so many others giving the wrong answer, I'm […]
  • GridView and Updating A Row ManuallyGridView and Updating A Row Manually A couple of days ago I mentioned a project that I’ve been working on that is a bit out of the ordinary as far as GridViews go.  One of the issues I’ve had is that the edit template […]
  • Test Sending Email without a Server in ASP.NETTest Sending Email without a Server in ASP.NET By now, most people are familiar with the fact that ASP.NET will send mail from the codebehind by simply adding a few lines to your web.config file and adding another few lines of code in […]
  • Embedding Google Search Appliance Results in ASP.NETEmbedding Google Search Appliance Results in ASP.NET Several of the projects I’m involved with use the Google Search Appliance for their search engine.  For each of these projects, we’ve wanted to integrate the results on an ASPX […]

About Dave Bush

Dave Bush is a Full Stack ASP.NET developer focusing on ASP.NET, C#, Node.js, JavaScript, HTML, CSS, BootStrap, and Angular.JS.Does your team need additional help in any of the above? Contact Dave today.

One Pingback/Trackback