How to get URL rewriting to work with ASP.Net 2.0 Themes and form post-backs

May 17th, 2007 | Tags:

Back in February, Scott Guthrie posted an article on URL rewriting with ASP.Net. Towards the end of the article there is a section on how to handle form post backs by sub classing HtmlForm (for ASP.Net 1.0 and 1.1) or by using a Control Adapter (for ASP.Net 2.0).

That seemed like a lot of work to get a viable solution so I decided to try and find a simpler solution before I “bit the bullet”. Additionally, ASP.Net 2.0 Themes do not always work with URL Rewriting and the article did not provide a solution.

The solution is to use the Application PostMapRequestHandler event to rewrite back to the original URL after the request has been mapped to its handler.

Following is an example that assume you are using ISAPI_Rewrite. ISAPI_Rewrite puts the originally requested URL in a requested header named HTTP_X_REWRITE_URL.

void Application_PostMapRequestHandler(object sender, EventArgs e)
{
    string originalUrl = Request.ServerVariables["HTTP_X_REWRITE_URL"];

    if (!string.IsNullOrEmpty(originalUrl))
    {
        Context.RewritePath(originalUrl);
    }
}

I have tested this method and have it working with extension-less URLs for both form post backs and ASP.Net 2.0 Themes.

  1. Dick Nagtegaal
    July 15th, 2009 at 01:05
    Reply | Quote | #1

    This code indeed is much simpler than using the Control Adapter approach. I have one problem with it however. When requesting the root of the application (i.e. http://www.example.com/) the value of HTTP_X_REWRITE_URL is ‘/’. For some reason this results in an “Object reference not set to an instance of an object” error.

    The stack trace shows no source file, but it starts with:
    [NullReferenceException: Object reference not set to an instance of an object.]
    System.Web.UI.Control.ResolveClientUrl(String relativeUrl) +124

    I’ve tried adding a rewrite rule to explicitely rewrite / to /Default.aspx (Rewrite ^$ /Default.aspx) but that doesn’t make a difference. Off course I can just check the originalUrl for being equal to “/” to prevent the problem.

    Can you confirm this behaviour? Any idea why it is happening?
    If you see the same behaviour, maybe you could adapt your code so it doesn’t occur.

    • Dick Nagtegaal
      July 15th, 2009 at 03:31
      Reply | Quote | #2

      I don’t know if I didn’t pay attention or if something changed (I’ve cleared my browser cache and restarted IIS), but now your code doesn’t seem to work at all. I have:
      RewriteRule ^IdList/(\d*)/(\d*)\.html$ /Default.aspx?Id=$1&SubId=$2

      When I request http://www.example.com/IdList/1/2.html I am indeed redirected to Default.aspx?Id=1&SubId=2.
      With just the rewrite rule and without your code, the action attribute of the form tag contains “Default.aspx?Id=1&SubId=2”. After adding your code it contains: “2.html?Id=1&SubId=2”.

      Although this does work, clicking a button on the form changes the url in the address bar to “http://www.example.com/IdList/1/2.html?Id=1&SubId=2”. The Control Adapter solution presented by Scott does not do that.

  2. May 16th, 2012 at 18:27
    Reply | Quote | #3

    Very nice post. I’m not using ISAPI_Rewrite, so I took a slightly different approach:

    In Application_BeginRequest, I added HttpContext.Current.Request.Url.AbsolutePath to the HttpContext.Current.Items collection. And then in Application_PostMapRequestHandler I pulled it back out and rewrote the URL just like you’re doing. Works like a charm.

    Keep up the good work.

  3. 1 trackbacks

TOP