Introduction
One of the biggest changes from ASP to ASP.NET is the postback process. By design, ASP.NET pages post form data back to themselves for processing. For most situations, this is an acceptable process. But if a page must post form data to another site or another ASP.NET page, this is impractical. The current ASP.NET postback process supports lots of ways to manage this process.
- Use
Server.Transfer()
to send posted fields to another page. This has the unfortunate side effect of not changing the user's URL.
- Pass the items on a querystring, bundling them manually and using
Response.Redirect()
to send the new querystring to another page. The querystring has both security and length issues.
- Pass the items on a post. Create a custom function to read the current items and send them via an HTTP post.
- Use an HTML form instead of a web form. Remove the
runat="server"
attribute from the Form
tag. Unfortunately, the validator controls can no longer be used, and that is the main reason I decided to use a JavaScript solution.
- Use a simple JavaScript function to alter the page behavior on the client.
I am going to describe a technique using a simple client-side JavaScript. The advantage of this is that it is quick and simple, especially for developers just starting out with ASP.NET or for simple applications. Additionally, when migrating ASP applications to ASP.NET, this little technique can help reduce migration time by allowing you to keep, the ASP page-to-page posting behavior. The one downside is that users can choose to operate their browser without JavaScript, thus negating this technique. If this is a serious concern for you, look into the third option listed above.
Background
There are two problems to overcome when using JavaScript to change the posting behavior of ASP.NET. The first problem is the self-postback. JavaScript allows the action
attribute of the HTML Form
tag to be changed on the client. It is the content of the post that causes ASP.NET to have the most serious problems. When an ASP.NET page receives a post, it checks for a field called __VIEWSTATE
(that's 2 underscore symbols) in the post. ASP.NET is using this field for many reasons, most outside the scope of this article. But, one thing the __VIEWSTATE
field does contain is internal validation for ASP.NET. If you simply post the __VIEWSTATE
field to a different ASP.NET page, than the page that filled the __VIEWSTATE
field, ASP.NET will throw an exception:
"The viewstate is invalid for this page and might be corrupted."
If we attempt to remove the data from the __VIEWSTATE
field prior to a post with JavaScript, the same exception is thrown.
So, in order to post to another ASP.NET page, the __VIEWSTATE
field cannot be passed to the next ASP.NET page. JavaScript allows us to rename the __VIEWSTATE
field and change the action
attribute of the form
tag.
Using the code
In the HTML portion of our ASP.NET page, we need to include the JavaScript function, NoPostBack
. It could reside in a separate file, but is included here in the page for simplicity.
<script language="javascript">
function noPostBack(sNewFormAction)
{
document.forms[0].action = sNewFormAction;
document.forms[0].__VIEWSTATE.name = 'NOVIEWSTATE';
}
</script>
The first line sets the form
's action
attribute to a new location that is passed to the function. The second line renames the __VIEWSTATE
field. It can be called anything other than it's original name or the name of your other form items. If you are trying to save bandwidth, you could also set the value of the __VIEWSTATE
field to ""
. In the ASP.NET Page_Load
function, only one line of code is necessary:
private void Page_Load(object sender, System.EventArgs e)
{
Submit.Attributes.Add("onclick", "noPostBack('secondform.aspx');");
}
This adds an onclick
attribute to the Submit button, and in this attribute we are specifying the new page or location for the post. When the button is clicked, it calls the JavaScript function before the form
post occurs, changing the default location from the page itself to somewhere else.
If the data is posted to another ASP.NET form, simply handle the form items using Request.Form
syntax:
private void Page_Load(object sender, System.EventArgs e)
{
Result.Text = Request.Form["SomeText"].ToString();
}
Points of interest
When dealing with Netscape 4 and a CSS-based layout, the JavaScript needs to adapt slightly. Each <div>
is considered a layer, so you must address the layer specifically in the JavaScript. Assume the form
is contained inside of a <div>
named Content
:
<div id="Content" name="Content">
<form method="post" id="Form1" runat="server">
</form>
</div>
The JavaScript now needs to differentiate between Netscape 4 and the other DOM aware browsers. Check for document.layers
to identify Netscape 4, and simply use the syntax appropriate for that browser:
<script language="javascript">
<!--
function noPostBack(sNewFormAction)
{
if(document.layers)
{
document.layers['Content'].document.forms[0].__VIEWSTATE.name =
'NOVIEWSTATE';
document.layers['Content'].document.forms[0].action =
sNewFormAction;
}
else
{
document.forms[0].action = sNewFormAction;
document.forms[0].__VIEWSTATE.name = 'NOVIEWSTATE';
}
}
-->
</script>