ASP.NET validation controls are very useful for validating user input that posts back to the same page. But how do you use these controls to validate input when posting to another page?
For example, let's say you have a page, WebPostAwayA1.aspx (shown in Figure 1), with two textbox controls that you wish to validate using a couple of RequiredFieldValidator controls. You wish to post the data to a second page, WebPostAway2.aspx, but only after the textbox entries have been validated.
Figure 1. The WebPostAwayA1.aspx page contains validation controls that require entries to the FirstName and LastName textboxes.
The body section of WebPostAwayA1.aspx is shown here:
The following code (shown in C#) on WebPostAwayA1.aspx will redirect to WebPostAway2.aspx if validation controls have validated the textbox entries:
void cmdPost_Click(Object src, EventArgs e ) {
if (Page.IsValid) {
Response.Redirect("WebPostAway2.aspx");
}
}
The problem, however, with this code is that the redirect method doesn't post the form control values to the WebPostAway2 page.
Using Server.Transfer
Now if you have ever played around with the ASP "classic" 3.0 methods you may be wondering "Why didn't he just use Server.Transfer?" since it passes along the forms collection when transferring to the new page. For example (from WebPostAwayB1.aspx):
void cmdPost_Click(Object src, EventArgs e ) {
if (Page.IsValid) {
Server.Transfer("WebPostAway2.aspx");
}
}
Well, in ASP.NET 1.0, Server.Transfer, by default does not pass along the form and querystring collections from a post back. However, you can set the second parameter of the Transfer method to true to force the form and querystring collections to be passed to the new page. Thus, you might rewrite the code like so (from WebPostAwayC1.aspx):
void cmdPost_Click(Object src, EventArgs e ) {
if (Page.IsValid) {
Server.Transfer("WebPostAway2.aspx", true);
}
}
Unfortunately, due to a bug in ASP.NET 1.0, this code causes a view state exception to be thrown as illustrated in Figure 2.
Figure 2. Forcing Server.Transfer to pass along the postback form values triggers this corrupted view state exception.
Fortunately, Microsoft is aware of this bug and has promised a fix in ASP.NET 1.1. (In fact, when used with the ASP.NET 1.1 beta, WebPostAwayB1.aspx works as you'd like, posting along the forms collection without any view state corruption.)
The Workaround
In the mean time, I've come up with a fairly generic work around that works by iterating through the Request.Form collection, copying the data from the forms collection to the querystring, and passing it to the new page in the Response.Redirect method.
Here's the complete code in C# from WebPostAwayD1.aspx:
void cmdPost_Click(Object src, EventArgs e ) {
if (Page.IsValid) {
string[] strKeys;
string[] strValues;
string strQs = "";
/* Build up querystring to match form collection.
Skip the view state field. */
strKeys = Request.Form.AllKeys;
for (int i = 0; i < Request.Form.Count; i++) {
strValues = Request.Form.GetValues(i);
for (int j = 0; j <= strValues.GetUpperBound(0); j++) {
if (strKeys[i] != "__VIEWSTATE")
strQs += strKeys[i] + "=" +
Server.UrlEncode(strValues[j]) + "&";
}
}
/* Get rid of extra "&" at end of strQs. */
if (strQs.Length > 0)
strQs = strQs.Substring(0, strQs.Length-1);
Response.Redirect("WebPostAway2.aspx?" + strQs);
}
}
The Request.Form collection in ASP.NET is of type NameValueCollection. Each item in a NameValueCollection consists of a key and an array of string values. This is necessary because in some cases form controls can have multiple values. The keys can be retrieved into an array using the AllKeys property:
strKeys = Request.Form.AllKeys;
The values associated with a particular key can be retrieved using the GetValues method:
strValues = Request.Form.GetValues(i);
Notice how the code skips over the view state field:
if (strKeys[i] != "__VIEWSTATE")
This is necessary because otherwise you will get a view state corruption exception. But even if you didn't get the exception, you wouldn't want to send along the view state because it's worthless on the new page.
Next, the code uses Sever.UrlEncode to encode the value, so it is safe for the querystring portion of a URL and appends it to the strQs string:
After a little fixup of strQs in which the last ampersand is jettisoned, the code redirects to the WebPostAway2.aspx page with the form values now reworked into the querystring:
Response.Redirect("WebPostAway2.aspx?" + strQs);
Using the WebPostAwayD1.aspx page, the form values should now be able to be retrieved from WebPostAway2.aspx using syntax like this:
Notice that I don't specify the particular collection of the Request object, which means that the values can come from either the querystring or form collection.
Figure 3 shows the form values retrieved from the querystring collection.
Figure 3. The WebPostAway2.aspx page retrieves the form field values from the querystring collection (notice the URL).
Caveats
The solution demonstrated in this article is far from perfect since the querystring is more visible and can hold less data than the forms collection. Even so, the presented solution works well in most scenarios. When ASP.NET 1.1 ships, this solution should be moot because Server.Transfer will be able to pass along the form collection of a self-posting form.
Downloading the Samples
The samples presented in the article are shown using C# but I have also created samples in Visual Basic .NET as well. You can download both sets of examples from here.
About the Author
Paul Litwin is a developer specializing in ASP, ASP.NET, Visual Basic, SQL Server, XML, and related technologies. He is one of the founders of Deep Training, a developer-owned training company providing exceptional training on Microsoft .NET (www.deeptraining.com), as well as the CEO of his consulting company, Litwin Consulting, Inc. Paul has authored several books including ASP.NET for Developers (SAMS) and Access 2002 Developer's Handbook (SYBEX). You can reach Paul at paull@deeptraining.com.
This sample chapter from Packt Publishing's "Building Websites with the ASP.NET Community Starter Kit"
illustrates how to build a new module on top of the existing code in the ASP.NET Community Starter Kit (CSK).
Using a Frequently Asked Questions (FAQ) module as an example, it shows how creating a new module allows you
to add entirely new features which integrate seamlessly with the rest of the framework. [Read This Article][Top]
Dino Esposito discusses the differences between the DataGrid control in
version 1.x and 2.0 of ASP.NET. In the process, he also builds an improved
version of the 1.x control that can get you some of the new 2.0 features
today. [Read This Article][Top]
Most default SharePoint Server Web Parts can be connected across organizations. The second article in this series shows how
to develop connectable Web Parts that provide information to other Web Parts. [Read This Article][Top]
Alex Homer continues to highlight some of the new ASP.NET 2.0 accessibility features. These features make it easier for visually impaired users to view and navigate Web sites and provide better support for alternative types of browsers and user agents. [Read This Article][Top]
Most default SharePoint Server Web Parts can be connected across organizations. The first article in this series explains how to connect existing Web Parts using the connection Interface classes in the SharePoint architecture. [Read This Article][Top]
Alex Homer highlights some of the new ASP.NET 2.0 accessibility features. These features make it easier for visually impaired users to view and navigate Web sites and provide better support for alternative types of browsers and user
agents. [Read This Article][Top]
Alex Homer discusses the simplification of, and extensions to, the ASP.NET 1.x data binding syntax, the new two-way data binding syntax for updating data sources, and the new syntax for binding to XML data in ASP.NET 2.0. [Read This Article][Top]
This article examines some of the new and exciting caching features in ASP.NET 2.0 and shows how to implement them in Web applications. [Read This Article][Top]
When implementing custom components that require access to restricted resources, implicit impersonation must be used. Jay Nathan shows how to create a class that makes using .NET Impersonation a snap. [Read This Article][Top]
Jeff Gonzalez demonstrates how to create a flexible configuration section
handler using C#. He provides a summary background of the .NET
configuration system, explains why the system is useful, and shows how it can be extended. [Read This Article][Top]
Mailing List
Want to receive email when the next article is published? Just Click Here to sign up.