![]() |
Web Development »
ASP.NET »
Samples
Beginner
License: The Code Project Open License (CPOL)
IIS vs. ASP.NET URL RewritingBy Alexandr Sergeevich IlyinA solution to use ASP.NET URL rewriting with virtual hosting and old IIS versions. |
C#, XML, .NET, ASP.NET, Dev, SysAdmin
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
It is important for web sites to have user friendly URLs, it helps search engine optimization and improves user-experience. In ASP.NET, nice URLs can be achieved by using URL rewriting, but deployment of such applications may be annoying. The problem is that when IIS receives a request like mydomain.com/products/3, it does not use ASP.NET to process it. Instead, IIS tries to find the file products/3 in the website folder and returns error 404 to the client. Unfortunately, there is no elegant solution, but an ugly one does exist.
If you have full control over the server where your application is hosted, you are lucky - it is enough to make all requests processed by the same DLL which processes .aspx files. Unfortunately, it is not always possible. For example, when virtual hosting or IIS 5 is used. So there is plan B. We configure the website to use error404.axd as the error 404 page URL. When a request like mydomain.com/products/3 is received, IIS will use ASP.NET to open error404.axd?http://mydomain.com/products/3. This allows us to use URL rewriting and fix up the URL.

public class Error404RewritingModule : IHttpModule
{
private static readonly FieldInfo HttpMethodFieldInfo;
private static readonly FieldInfo HttpVerbFieldInfo;
public void Init(HttpApplication context)
{
context.BeginRequest += OnBeginRequest;
}
static void OnBeginRequest(object sender, EventArgs e)
{
HttpContext httpContext = HttpContext.Current;
HttpRequest httpRequest = httpContext.Request;
//
string targetPath = httpRequest.AppRelativeCurrentExecutionFilePath;
if (!targetPath.StartsWith("~/Error404.axd",
StringComparison.InvariantCultureIgnoreCase))
return;
Uri requestedUrl = httpRequest.Url;
var currentApplicationUrl = new Uri(requestedUrl, httpRequest.ApplicationPath);
//
// Extract initially requested url
string initiallyRequestedUrl = ExtractInitiallyRequestedUrl(requestedUrl.Query);
string initiallyRequestedQuery = ExtractInitiallyRequestedQuery(initiallyRequestedUrl);
string initiallyRequestedVirtualPath = GetInitiallyRequestedVirtualPath(
currentApplicationUrl, initiallyRequestedUrl);
if (String.IsNullOrEmpty(initiallyRequestedQuery))
httpContext.RewritePath("~/Hack", "/", "a=b", true);
if (!String.Equals(httpRequest.HttpMethod, "POST",
StringComparison.InvariantCultureIgnoreCase))
if (httpRequest["__VIEWSTATE"] != null ||
httpRequest["__EVENTTARGET"] != null) {
HttpMethodFieldInfo.SetValue(httpRequest, "POST");
HttpVerbFieldInfo.SetValue(httpRequest, 5); // 5 = POST
}
httpContext.RewritePath(initiallyRequestedVirtualPath, null, "", true);
}
...
}
There are two interesting places; the first is the following:
if (String.IsNullOrEmpty(initiallyRequestedQuery))
httpContext.RewritePath("~/Hack", "/", "a=b", true);
It would take a deep diving into ASP.NET internals to explain this, but the reason is the following. If the query string is empty, then HttpRequest.Current.Url is not changed by rewriting sometimes. The second place of interest is:
if (!String.Equals(httpRequest.HttpMethod, "POST",
StringComparison.InvariantCultureIgnoreCase))
if (httpRequest["__VIEWSTATE"] != null || httpRequest["__EVENTTARGET"] != null) {
HttpMethodFieldInfo.SetValue(httpRequest, "POST");
HttpVerbFieldInfo.SetValue(httpRequest, 5); // 5 = POST
}
It is required because IIS 6.0 passes a GET request to Error404.axd, even if the client sends POST. So this code hacks HttpRequest to make it POST again.
httpModules configuration section:<httpModules> <add name="LiveUI.Error404-Handler" type="Xtensive.Web.Error404RewritingModule, Xtensive.Web"> </httpModules>

If you use virtual hosting, it will look like this:

You might not like the solution presented, neither do I, but it is better than nothing. Initially, I developed this module to help LiveUI users to deploy their applications, so it was tested on LiveUI demos. But there should be no problems in using it with other frameworks such as ASP.NET MVC or UrlRewriting.NET.
| You must Sign In to use this message board. | ||||||
|
||||||
|
||||||
|
||||||
General
News
Question
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 23 Nov 2009 Editor: Smitha Vijayan |
Copyright 2009 by Alexandr Sergeevich Ilyin Everything else Copyright © CodeProject, 1999-2010 Web21 | Advertise on the Code Project |