1.6. Post to Another Page
Note: ASP.NET 2.0 now allows you to post values from one page to another easily.
Most ASP.NET developers are familiar with the postback feature of ASP.NET server controls. However, in some cases, posting back to the same page is not the desired actionyou might need to post to another. For example, you might need to build an application to perform some surveys. Instead of displaying 50 questions on one page, you would like to break it down to 10 questions per page so that the user need not wade through 50 questions in one go. Moreover, answers to certain questions might trigger a related set of questions in another page. In this case, using a conventional postback mechanism for your web pages is clearly not the solution. You might want to post the values (i.e., the answers to the questions) of one page to another. In this situation, you need to be able to cross-post to another page and, at the same time, be able to retrieve the values from the previous page.
In ASP.NET 1.0 and 1.1, there is no easy way to transfer to another page, and most developers resort to using Server.Transfer. Even so, passing values from one page to another this way is a challenge.
In ASP.NET 2.0, cross-page posting is much easier. Controls now inherently support posting to another page via the PostBackUrl attribute.
1.6.1. How do I do that?
To see cross-page posting in action, you will create an application that contains two pages. One page lets you choose items from a CheckBoxList control and then lets you cross-post to another page. You will learn how the values that were cross-posted can be retrieved in the destination page. In addition, you will see the difference between cross-page posting and the old Server.Transfer( ) method.
In Visual Studio 2005, create a new web site project and name it C:\ASPNET20\chap01-CrossPagePosting.
Populate the default Web Form with the controls shown in Figure 1-18. The CheckBoxList1 control contains CheckBox controls that let users choose from a list of values. When the "Post to Default2.aspx" button is clicked, you will post the values to Default2.aspx using the new cross-page posting feature in ASP.NET 2.0. The "Transfer to Default2.aspx" button uses Server.Transfer to load Default2.aspx.
Figure 1-18. Populating the default Web Form
Add a new Web Form to your project and populate it with a Button control (see Figure 1-19).
Figure 1-19. Populating the Default2 Web Form
In Default.aspx, switch to Source View and add the PostBackUrl attribute to btnPost so that it can perform a cross-page post to Default2.aspx:
<asp:Button PostBackUrl="~/Default2.aspx" runat="server" Text="Post to Default2.aspx" />
For btnTransfer, add the following code-behind:
Protected Sub btnTransfer_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles btnTransfer.Click Server.Transfer("Default2.aspx") End Sub
In order for Default2.aspx to access the value of the CheckBoxList1 control in Default.aspx, expose a public property in Default.aspx. To do so, switch to the code-behind of Default.aspx and type in the following code shown in bold:
Partial Class Default_aspx Inherits System.Web.UI.Page Public ReadOnly Property ServerSide( ) As CheckBoxList Get Return CheckBoxList1 End Get End Property Protected Sub btnTransfer_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles btnTransfer.Click Server.Transfer("Default2.aspx") End Sub End Class
Note: You need to expose public properties in the first page in order for the other page to access it. This has the advantage of early binding and facilitates strong typing.
In Default2.aspx, you need to specify that Default.aspx is going to post to it by using the PreviousPageType directive. In Default2.aspx, switch to Source View and add the PreviousPageType directive:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default2.aspx.vb" Inherits="Default2_aspx" %> <%@ PreviousPageType VirtualPath="~/Default.aspx" %>
When Default.aspx posts to Default2.aspx, all the information about Default.aspx is encapsulated in a special property known as PreviousPage. When Default2.aspx loads, you must first determine whether it was posted by Default.aspx or it gets loaded by itself. So check if PreviousPage contains a reference:
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If PreviousPage IsNot Nothing Then ...
Then check if this is a cross-page post or a Server.Transfer by using the new IsCrossPagePostBack property. This property will be true if Default.aspx cross-posts to Default2.aspx, false if Default.aspx performs a Server.Transfer to Default2.aspx:
If PreviousPage IsNot Nothing Then '--checks the type of posting If PreviousPage.IsCrossPagePostBack Then Response.Write("This is a cross-post") Else Response.Write("This is a Server.Transfer") End If
Note: Check the IsCrossPagePostBack property to see if there is a cross posting.
Finally, display the selections made in the CheckBoxList control in Default.aspx:
Response.Write("<br/>You have selected :") Dim i As Integer For i = 0 To PreviousPage.ServerSide.Items.Count - 1 If PreviousPage.ServerSide.Items(i).Selected Then Response.Write( _ PreviousPage.ServerSide.Items(i).ToString & " ") End If Next
Tip: The ServerSide property refers to the property exposed in Default.aspx. The advantage to exposing properties in the page is that the data is strongly typed.
The entire block of code is as shown:
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles Me.Load If PreviousPage IsNot Nothing Then '--checks the type of posting If PreviousPage.IsCrossPagePostBack Then Response.Write("This is a cross-post") Else Response.Write("This is a Server.Transfer") End If Response.Write("<br/>You have selected :") Dim i As Integer For i = 0 To PreviousPage.ServerSide.Items.Count - 1 If PreviousPage.ServerSide.Items(i).Selected Then Response.Write( _ PreviousPage.ServerSide.Items(i).ToString & " ") End If Next End If End Sub
To see the example in action, Figure 1-20 shows a cross-page post.
Figure 1-20. Cross-posting from Default.aspx to Default2.aspx
Figure 1-21 shows posting to Default2.aspx via the Server.Transfer method. Note the URL of both pages (they are the same for Server.Transfer).
Figure 1-21. Using Server.Transfer to post from Default.aspx to Default2.aspx
If you click the button "Postback to myself" in Default2.aspx, you will notice that the information from Default.aspx is no longer displayed; a postback will clear the object reference in the PreviousPage property.
Tip: The main difference between a cross-page post and the use of Server.Transfer is that, in the case of the Server.Transfer, the URL does not change to the new page.
1.6.2. What about...
...having multiple pages post to the same page?
In this case, you would not be able to use the early binding mechanism accorded by the PreviousPage property, because the PreviousPageType directive predefines the type of a previous page:
<%@ PreviousPageType VirtualPath="~/default.aspx" %>
So if there are different pages posting to a common page, having this directive is not useful, because those pages may have different controls and types. Hence, a better way would be to use late-binding via the FindControl( ) method.
Example 1-1 shows how you can use the AppRelativeVirtualPath property of the PreviousPage property to get the address of the last page posted to it. The application then uses the FindControl( ) method to locate the controls within the source page.
Note: Use the FindControl( ) method to locate values in the previous page if multiple pages post to one page.
Example 1-1. Locating the controls of the last page to post
If PreviousPage.AppRelativeVirtualPath = "~/Default.aspx" Then Dim serverSide As CheckBoxList serverSide = CType(PreviousPage.FindControl("checkboxlist1"), _ System.Web.UI.WebControls.CheckBoxList) If serverSide IsNot Nothing Then Dim i As Integer For i = 0 To serverSide.Items.Count - 1 If serverSide.Items(i).Selected Then Response.Write(serverSide.Items(i).ToString & " ") End If Next End If ElseIf PreviousPage.AppRelativeVirtualPath = "~/Default3.aspx" Then Dim userName As TextBox userName = CType(PreviousPage.FindControl("txtName"), _ System.Web.UI.WebControls.TextBox) If userName IsNot Nothing Then Response.Write(userName.Text) End If End If
Tip: If you attempt to cross-post between two different applications, the PreviousPage property will be set to Nothing (or null in C#).
1.6.3. Where can I learn more?
To learn more about the various ways to redirect users to another page, check out the Microsoft Visual Studio 2005 Documentation Help topic "Redirecting Users to Another Page."