Recipe 4.3. Submitting a Form to a Different Page


Problem

You need to submit the information on one pagea form, for exampleto another. You might want to do this to use one page to collect form data and a second page to process it.

The default operation for ASP.NET is to submit the form to the same page. Submitting the form to a different pagei.e., performing cross-page postingrequires some coding gymnastics in ASP.NET 1.x, explained in some detail in the first edition of the ASP.NET Cookbook:

  • Using the Server.Transfer method in a button click event handler in the code-behind of the first page to transfer control to a second page, after saving the contents of the first in session scope.

  • Using the Server.Transfer method in a button click event handler in the code-behind of the first page to transfer control, along with the form contents in the ViewState, to the second page.

In ASP.NET 2.0, however, performing cross-page posting is easier because you can now accomplish it by setting the PostBackUrl button property.


Solution

Use the cross-page posting functionality added to ASP.NET 2.0 to submit a form to a different page.

In the .aspx file of the first page, set to the URL of the desired page the PostBackUrl property of the button that will initiate the submission of the form to another page. No special code is required in the code-behind of the first page to support cross-page posting.

In the code-behind of the second page, use the .NET language of your choice to:

  1. Check to verify that page is being requested as a cross-page post from another page.

  2. Use the FindControl method of the PreviousPage property to get a reference to a control in the first page.

  3. Use the data from the control in the first page as required in the second page.

  4. Repeat the last two steps for each control in the first page that you need data for in the second page.

Examples 4-4, 4-5, 4-6, 4-7, 4-8 through 4-9 showthe .aspx and code-behind files for an application that implements this solution.

Discussion

The default operation for ASP.NET is to submit the form to the same page for processing. This operation is acceptable for most applications; however, the need may arise to submit the form to another page. This is much easier to do in ASP.NET 2.0 than in previous versions. In fact, prior to ASP.NET 2.0, submitting a form to another page required working around the system instead of with it.

In ASP.NET 2.0, the submission to another page is controlled by the PostBackURL property of the buttons on the form. This provides the ability to submit the form to different pages for each button.

  <asp:Button  runat="server" Text="Submit" PostBackUrl="~/CH04SubmitToAnother_SecondPageVB1.aspx" /> 

You cannot set the action attribute of the form element to cause the form to be submitted to another page. ASP.NET always changes the action to the URL of the page being displayed.


When the user clicks the submit button, ASP.NET executes a client-side JavaScript method that performs the submission to the second page, passing the information necessary for the second page to determine if the request is the result of a cross-page post, as well as the data to rehydrate the page object for the first page.

You can determine if a page is being requested as a result of a cross-page post by checking if the PreviousPage property of the Page object is null (Nothing in VB):

 

If (IsNothing(Page.PreviousPage)) Then 'page is not being accessed by a cross-page postback Else 'page is being accessed by a cross-page postback End If

if (Page.PreviousPage == null) { // page is not being accessed by a cross-page postback } else { // page is being accessed by a cross-page post-back }

The first time you access the PreviousPage property, ASP.NET rehydrates the page object for the first page. As part of the rehydration, all events up to LoadComplete are fired. This includes the button click event for the submit button that was clicked. If your code contains an event handler for the click event for the buttons used to submit to another page, this code will be executed.


By accessing the PreviousPage property, your code can access the content of the controls on the first page. Since the PreviousPage property is of type Page, you cannot directly access the controls. You have to use the FindControls method to get a reference to the desired control and then access the data in the control.

 

get the page content control 'NOTE: This is required since a master page is being used and the ' controls that contain the data needed here are within it pageContent = CType(Page.PreviousPage.Form.FindControl("PageBody"), _ ContentPlaceHolder) 'get the first name data from the first page and set the label 'on this page tBox = CType(pageContent.FindControl("txtFirstName"), _ TextBox) lblFirstName.Text = tBox.Text

// get the page content control // NOTE: This is required since a master page is being used and the // controls that contain the data needed here are within it pageContent = (ContentPlaceHolder) (Page.PreviousPage.Form.FindControl("PageBody")); // get the first name data from the first page and set the label // on this page tBox = (TextBox)(pageContent.FindControl("txtFirstName")); lblFirstName.Text = tBox.Text;

If the control you are accessing is contained within another control, such as a template or a content placeholder, you need to use FindControl to get a reference to the container first and then use FindControl again to get a reference to the control containing your data.


Though the solution shown above works fine and is acceptable in most applications, it has two problems. First, you must have knowledge of the structure of the first page to get a reference to the desired controls in the second (described above). This can become complicated if the controls on the first page are embedded in multiple layers of control containers. Second, the access to the controls is not strongly typed, requiring you to cast the control type for access. If the control type changes on the first page, the code in the second page must also be changed.

Another solution that eliminates these problems is to add public properties to the code-behind of the first page that expose the data in the controls that you need in the second page:

 

'''******************************************************************** ''' <summary> ''' This routine provides the ability to get/set the firstName property ''' </summary> Public Property firstName() As String Get Return (txtFirstName.Text) End Get Set(ByVal value As String) txtFirstName.Text = value End Set End Property '''******************************************************************** ''' <summary> ''' This routine provides the ability to get/set the lastName property ''' </summary> Public Property lastName() As String Get Return (txtLastName.Text) End Get Set(ByVal value As String) txtLastName.Text = value End Set End Property '''******************************************************************* ''' <summary> ''' This routine provides the ability to get/set the age property ''' </summary> Public Property age() As String Get Return (txtAge.Text) End Get Set(ByVal value As String) txtAge.Text = value End Set End Property

///******************************************************************** /// <summary> /// This routine provides the ability to get/set the firstName property /// </summary> public String firstName { get { return (txtFirstName.Text); } set { txtFirstName.Text = value; } } // firstName ///******************************************************************* /// <summary> /// This routine provides the ability to get/set the lastName property /// </summary> public String lastName { get { return (txtLastName.Text); } set { txtLastName.Text = value; } } // lastName ///******************************************************************* /// <summary> /// This routine provides the ability to get/set the age property /// </summary> public String age { get { return (txtAge.Text); } set { txtAge.Text = value; } } // age

In the .aspx file of the second page, add the PreviousPageType directive to the top of the file with the VirtualPath attribute set to the URL of the first page:

 <%@ Page Language="VB" MasterPageFile="~/ASPNetCookbookVB.master"   AutoEventWireup="false"   CodeFile="CH04SubmitToAnother_SecondPageVB2.aspx.vb"   Inherits="ASPNetCookbook.VBExamples.CH04SubmitToAnother_SecondPageVB2"   Title="Form Submission To Another Page - Second Page - Approach 2" %>     <%@ PreviousPageType VirtualPath="~/CH04SubmitToAnother_FirstPageVB2.aspx" %> 

References to pages, images, and other resources are typically prefaced with "~/", which is used to indicate the root folder of the web application.


In the code-behind of the second page, define a variable of the type of the first page and set its value to the PreviousPage property of the Page object:

 

Dim prevPage As CH04SubmitToAnother_FirstPageVB2 'get a strongly type reference to the previous page prevPage = CType(Page.PreviousPage, _ CH04SubmitToAnother_FirstPageVB2)

CH04SubmitToAnother_FirstPageCS2 prevPage; // get a strongly type reference to the previous page prevPage = (CH04SubmitToAnother_FirstPageCS2)(Page.PreviousPage);

With the strongly typed reference to the first page, you can directly access the properties you added to access the required data:

 

lblFirstName.Text = prevPage.firstName lblLastName.Text = prevPage.lastName lblAge.Text = prevPage.age

lblFirstName.Text = prevPage.firstName; lblLastName.Text = prevPage.lastName; lblAge.Text = prevPage.age;

This second solution is cleaner and less likely to break when the code is changed during future maintenance operations. It does require a little more planning and coding but it is worth the effort.

See Also

Search ASP.NET 2.0 Internals in the MSDN Library.

Example 4-4. Submitting a form to another pagefirst page (.aspx)

 <%@ Page Language="VB" MasterPageFile="~/ASPNetCookbookVB.master"   AutoEventWireup="false"   CodeFile="CH04SubmitToAnother_FirstPageVB1.aspx.vb"   Inherits="ASPNetCookbook.VBExamples.CH04SubmitToAnother_FirstPageVB1"   Title="Form Submission To Another Page - Approach 1" %> <asp:Content  Runat="server" ContentPlaceHolder>    <div align="center" >       Form Submission To Another Page - Approach 1 (VB)    </div>    <table width="50%" align="center" border="0">    <tr>      <td >First Name: </td>  <td>     <asp:TextBox  Runat="server" Columns="30" Css /> </td>   </tr>   <tr>      <td >Last Name: </td>  <td>  <asp:TextBox  Runat="server" Columns="30" Css /> </td>   </tr>   <tr>  <td >Age: </td>  <td>    <asp:TextBox  Runat="server" Columns="30" Css /> </td>   </tr>   <tr>      <td align="center" colspan="2">    <br/>    <asp:Button  runat="server"   Text="Submit"   PostBackUrl="~/CH04SubmitToAnother_SecondPageVB1.aspx" />   </td> </tr>   </table> </asp:Content> 

Example 4-5. Submitting a form to another pagefirst page (.vb)

 Option Explicit On Option Strict On Namespace ASPNetCookbook.VBExamples ''' <summary> ''' This class provides the code behind for ''' CH04SubmitToAnother_FirstPageVB1.aspx ''' </summary> Partial Class CH04SubmitToAnother_FirstPageVB1 Inherits System.Web.UI.Page '''**************************************************************** ''' <summary> ''' This routine provides the event handler for the page load event. It ''' is responsible for initializing the controls on the page. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Protected Sub Page_Load(ByVal sender As Object, _    ByVal e As System.EventArgs) Handles Me.Load     End Sub 'Page_Load     End Class 'CH04SubmitToAnother_FirstPageVB1 End Namespace 

Example 4-6. Submitting a form to another pagefirst page (.cs)

 using System; namespace ASPNetCookbook.CSExamples {    /// <summary>    /// This class provides the code behind for    /// CH04SubmitToAnother_FirstPageCS1.aspx    /// </summary>    public partial class CH04SubmitToAnother_FirstPageCS1 : System.Web.UI.Page    {     ///******************************************************************* /// <summary>     /// This routine provides the event handler for the page load event. /// It is responsible for initializing the controls on the page. /// </summary> /// /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param> protected void Page_Load(object sender, EventArgs e)     { } // Page_Load   } // CH04SubmitToAnother_FirstPageCS1 } 

Example 4-7. Submitting a form to another pagesecond page (.aspx)

 <%@ Page Language="VB" MasterPageFile="~/ASPNetCookbookVB.master"    AutoEventWireup="false"    CodeFile="CH04SubmitToAnother_SecondPageVB1.aspx.vb"    Inherits="ASPNetCookbook.VBExamples.CH04SubmitToAnother_SecondPageVB1"    Title="Form Submission To Another Page - Second Page - Approach 1" %> <asp:Content  Runat="server" ContentPlaceHolder>     <div align="center" >    Form Submission To Another Page - Approach 1 (VB) </div> <table width="50%" align="center" border="0">   <tr>     <td colspan="2" align="center" >   Data Submitted From Previous Page </td>   </tr>   <tr>      <td >First Name: </td>  <td > <asp:Label  Runat="server" />  </td>    </tr>  <tr> <td >Last Name: </td> <td > <asp:Label  Runat="server" /> </td> </tr> <tr> <td >Age: </td> <td > <asp:Label  Runat="server" /> </td> </tr> <tr> <td colspan="2">&nbsp;</td> </tr> <tr>     <td >Page Access Method: </td> <td > <asp:Label  Runat="server" /> </td> </tr> </table> </asp:Content> 

Example 4-8. Submitting a form to another pagesecond page (.vb)

 Option Explicit On Option Strict On Imports System.Web.UI.WebControls Namespace ASPNetCookbook.VBExamples    ''' <summary>    ''' This class provides the code behind for    ''' CH04SubmitToAnother_SecondPageVB1.aspx    ''' </summary> Partial Class CH04SubmitToAnother_SecondPageVB1 Inherits System.Web.UI.Page '''****************************************************************** ''' <summary> ''' This routine provides the event handler for the page load event. It ''' is responsible for initializing the controls on the page. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load Dim tBox As TextBox Dim pageContent As ContentPlaceHolder  'check to see how the page is being accessed If (IsNothing(Page.PreviousPage)) Then 'page is not being accessed by cross-page post so check to if 'it is being accessed via self post-back If (Page.IsPostBack) Then 'page is being accessed by a post-back from itself lblPageAccessMethod.Text = "Page was accessed via post-back" Else 'page is being accessed directly lblPageAccessMethod.Text = "Page was accessed directly" End If Else 'page is being accessed by a cross-page post-back lblPageAccessMethod.Text = "Page was accessed via cross-page post-back" 'get the page content control 'NOTE: This is required since a master page is being used and the '        controls that contain the data needed here are within it pageContent = CType(Page.PreviousPage.Form.FindControl("PageBody"), _ ContentPlaceHolder) 'get the first name data from the first page and set the label 'on this page tBox = CType(pageContent.FindControl("txtFirstName"), _   TextBox) lblFirstName.Text = tBox.Text   'get the last name data from the first page and set the label 'on this page tBox = CType(pageContent.FindControl("txtLastName"), _  TextBox) lblLastName.Text = tBox.Text   'get the age data from the first page and set the label 'on this page tBox = CType(pageContent.FindControl("txtAge"), _ TextBox) lblAge.Text = tBox.Text   End If End Sub 'Page_Load End Class 'CH04SubmitToAnother_SecondPageVB1 End Namespace 

Example 4-9. Submitting a form to another pagesecond page (.cs)

 using System; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples {   /// <summary>   /// This class provides the code behind for   /// CH04SubmitToAnother_SecondPageCS1.aspx  /// </summary>  public partial class CH04SubmitToAnother_SecondPageCS1 : System.Web.UI.Page  { ///********************************************************************* /// <summary> /// This routine provides the event handler for the page load event. /// It is responsible for initializing the controls on the page. /// </summary> /// /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param> protected void Page_Load(object sender, EventArgs e) { TextBox tBox; ContentPlaceHolder pageContent;    // check to see how the page is being accessed  if (Page.PreviousPage == null)  {     // page is not being accessed by cross-page post so check to if // it is being accessed via self post-back if (Page.IsPostBack) {   // page is being accessed by a post-back from itself   lblPageAccessMethod.Text = "Page was accessed via post-back"; } else {   // page is being accessed directly   lblPageAccessMethod.Text = "Page was accessed directly";         }   }   else   {      // page is being accessed by a cross-page post-back  lblPageAccessMethod.Text = "Page was accessed via cross-page post-back";  // get the page content control  // NOTE: This is required since a master page is being used and the  //     controls that contain the data needed here are within it  pageContent = (ContentPlaceHolder)    (Page.PreviousPage.Form.FindControl("PageBody"));  // get the first name data from the first page and set the label  // on this page  tBox = (TextBox)(pageContent.FindControl("txtFirstName"));  lblFirstName.Text = tBox.Text;    // get the last name data from the first page and set the label  // on this page  tBox = (TextBox)(pageContent.FindControl("txtLastName"));  lblLastName.Text = tBox.Text;    // get the age data from the first page and set the label  // on this page  tBox = (TextBox)(pageContent.FindControl("txtAge"));  lblAge.Text = tBox.Text;   } }  // Page_Load   } // CH04SubmitToAnother_SecondPageCS1 } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2003
Pages: 202

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net