Table of Contents
This article describes an idea of the ASP.NET page transfer method that can be called like the Response.Redirect
method and works as cross-page posting.
When I develop ASP.NET applications, I often use cross-page posting to transfer and to pass page data to another page. The advantage of cross-page posting is that the transferred page can access the previous page to retrieve page data. It reduces the cost of session management. So, I prefer to use cross-page posting.
But, there is one thing I don't like about cross-page posting; it can't perform in an event handler. When we set value to the Button.PostBackUrl
property to perform cross-page posting, unfortunately, the click event handler doesn't work. For this reason, if we want to transfer to another page after doing something in an event handler, we can't use cross-page posting.
Thus, when we use cross-page posting, we have to use several implementation techniques. In some cases, we have to set the PostBackUrl
property to perform cross-page posting. And in other cases, we have to implement an event handler to transfer to another page with the Response.Redirect
method after doing something (although the HttpServerUtility.Transfer
method can also be used, I don't want to use it). In addition, then, we must use session or query string to pass data to another page.
Consequently, the implementation of page transfer and data passing becomes complex.
To mitigate this complexity, I have come up with a mechanism that performs cross-page posting in an event handler. It always allows us to transfer and to pass data to another page with cross-page posting.
The concept of my idea is illustrated in Fig 1.
Fig 1. The concept of my idea.
The following are the main points of my idea:
- Use an async postback to request server
- Return a cross-page posting script as the response of the async postback
- Evaluate the returned script
- Retrieve previous page data with the
PreviousPage
property
The ScriptManager.endRequest
event will be raised when an async postback is completed. So, this event allows you to perform additional processes in client-side after completion of an async postback.
The ClientScriptManager.GetPostBackEventReference
method allows you to create a cross-page posting script in a server-side event handler. This method returns a cross-page posting script as string
when you pass an instance of the PostBackOption
class that is set up appropriately.
The ScriptManger.RegisterDataItem
method can be used to return the created script as the response. This method allows you to store any data in the dataItems
array. And, the dataItems
array can be accessed in the endRequest
event handler.
In the endRequest
event handler, you can retrieve the returned cross-page posting script via the dataItems
array. When you pass its script to the eval
method, the cross-page posting is performed.
As with normal cross-page posting, previous page data can be accessed with the PreviousPage
property from a next page. Naturally, the PreviousPageType
directive also works.
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="scriptManager" runat="server" />
<asp:UpdatePanel ID="updatePanel" runat="server">
<ContentTemplate>
<asp:Button ID="submitButton" runat="server"
Text="Submit" OnClick="Submit" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
Code 1. A part of Page1.aspx
using System;
using System.Text;
using System.Web;
using System.Web.UI;
namespace SampleCode
{
public partial class Page1 : Page
{
public string OrderNo
{
get
{
return (string)ViewState["OrderNo"];
}
private set
{
ViewState["OrderNo"] = value;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
StringBuilder script = new StringBuilder();
script.Append("var manager =
Sys.WebForms.PageRequestManager.getInstance();");
script.Append("manager.add_endRequest(function(sender, args) {");
script.Append(" if (args.get_error() == undefined) {");
script.Append(" var dataItems = args.get_dataItems();");
script.Append(" var item = dataItems['" + ClientID + "'];");
script.Append(" if (item != undefined) {");
script.Append(" eval(item);");
script.Append(" }");
script.Append(" }");
script.Append("});");
ClientScript.RegisterStartupScript(GetType(),
"doCrossPagePostBack", script.ToString(), true);
}
protected void Submit(object sender, EventArgs e)
{
Random r = new Random();
OrderNo = String.Format("OD{0:00000000}", r.Next(0, 99999999));
NavigateTo("~/Page2.aspx");
}
private void NavigateTo(string url)
{
ScriptManager manager = ScriptManager.GetCurrent(this);
if (manager.IsInAsyncPostBack)
{
if (VirtualPathUtility.IsAbsolute(url) == false)
{
url = VirtualPathUtility.ToAbsolute(url);
}
PostBackOptions o = new PostBackOptions(this, String.Empty, url,
false, false, false, true, false, String.Empty);
manager.RegisterDataItem(this,
ClientScript.GetPostBackEventReference(o));
}
}
}
}
Code 2. Page1.aspx.cs
<body>
<form id="form1" runat="server">
<asp:Label ID="orderNoLabel" runat="server" Text="Order No :" />
<asp:Label ID="orderNoValueLabel" runat="server" />
</form>
</body>
Code 3. A part of Page2.aspx
using System;
using System.Web.UI;
namespace SampleCode
{
public partial class Page2 : Page
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
{
Page1 previousPage = (Page1)PreviousPage;
this.orderNoValueLabel.Text = previousPage.OrderNo;
}
}
}
}
Code 4. Page2.aspx.cs