ASP.NET postbacks and URL rewriting

ASP.NET Web Forms extensively use postback mechanism in order to maintain the state of the server-side controls on the web page. This makes it somewhat tricky to perform URL rewriting for ASP.NET pages. When a server side form control is added to the web page, ASP.NET will render the response with HTML <form> tag that contains an action attribute pointing back to the page where the form control is. This means that if URL rewriting was used for that page, the action attribute will point back to the rewritten URL, not to the URL that was requested from the browser. This will cause the browser to show rewritten URL any time a postback occurs.

Let me demonstrate this on an example. Assume you have a very simple web form in a file called default.aspx. When you request http://localhost/default.aspx in a browser and then view the HTML source for the response, you will see that the response contains the <form> element, which looks similar to this:

<form name="form1" method="post" action="Default.aspx" id="form1">

The action attribute contains the URL where the form data will be posted to when you click on the button in the web page.

Now, let’s create a very simple rewrite rule that rewrites URL from http://localhost/homepage to http://localhost/default.aspx.

 
<rewrite>
  <rules>
    <rule name="MyRule" patternSyntax="Wildcard">
      <match url="homepage" />
      <action type="Rewrite" url="default.aspx" />
    </rule>
  </rules>
</rewrite>

When you request http://localhost/homepage in a browser, the URL will be rewritten in accordance to the above rule and the page will be shown correctly in the browser:

Postback1

However, when you click on the Submit button, the browser’s address bar will display http://localhost/default.aspx, thus exposing the internal URL, that you wanted to hide by using URL rewriting:

Postback2

A few workarounds to fix this behavior existed in previous versions of ASP.NET. For example, you could sub-class the form control, or use Control Adapter as explained here. However, these workarounds were not very easy to implement. Luckily, the ASP.NET in .NET Framework 3.5 SP1 provides a very simple way to fix that. Now you can use the property of the HtmlForm class called Action to set the postback URL to the one that was requested by browser before any rewriting happened. In ASP.NET you can obtain that URL by using HttpRequest.RawUrl property. So, to fix the postback URL for your web form when you use URL Rewrite Module, you would need to add the following code to the page:

 
protected void Page_Load(object sender, EventArgs e)
{
    form1.Action = Request.RawUrl;
}

After this change, if you reload the web page at http://localhost/homepage and then click on submit button you will see that the browser’s address bar still displays the correct URL:

Postback3

If you view the HTML for the response you will see that the <form> tag now contains the correct action URL:

 
<form name="form1" method="post" action="/homepage" id="form1">

When you use ASP.NET master pages you could add the Page_Load method to the master page and that would take care of postback action URL for all the pages in your web application. Note thought that in order to be able to use the HtmlForm.Action property you have to upgrade to .NET Framework 3.5 SP1.