Introduction
This whole thing started out simple. All I wanted to do was pass a single variable back and forth between two pages in an admin section of a website using cross page postback. Were it not for my use of a master page, I would not be writing about this. Without a master, all you need to use is find the control. However, with a master page, things get more complicated. I’ll not go into it more than to say you need to find the control via the clientID
, and you need to somehow get that ID in ways that I consider prone to error. Therefore, I opted for strong typing of the previous page. This nailed me with another issue. It works great one way, but not two ways. From x.aspx to y.aspx - no problem, but from y.aspx back to x.aspx - error! Well, it took me a while, but I figured out how to do it cleanly; in one word: Interface.
Let’s start by reviewing the three methods for cross page postback. I have two variables I need to pass, iItemID
and iClientID
, between two pages, x.aspx and y.aspx.
PreviousPage.FindControl("lbl_iItemID")
where lbl_iItemID
is a Label
on the previous page with the value you want to get. This gave me problems with a master page, necessitating some wordy and sloppy code. Sloppy in at least the way I was doing it!
- Strong typing of the previous page. Here you add a
<%@ PreviousPageType VirtualPath="sourcepage.aspx" %>
in the receiving page. This is a reference to the previous page, so you can just use a PreviousPage.lbl_iItemID.Text
to get the value. The problem here is when you try to go back to the first page, you get an error noting a circular reference. In other words, x to y is on, but y to x is error.
- This one is not common, but it should be! Use an interface. From here forward, this is what I will be using for all cross page post backs. It allows you to create a discrete number of strongly typed arguments that can be referenced by any page you decide that needs to receive or pass variables.
The interface method
I will outline how I consider it should be done:
- Create the interface. This one is simple, with only two items.
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
public interface ICommonPostback
{
int IItemID
{ get; set; }
int IClientUploadID
{ get; set; }
}
Save as ICommonPostback.cs.
- Reference the interface in your two pages like this, by adding
ICommonPostBack
:
public partial class Admin_y : System.Web.UI.Page, ICommonPostback
public partial class Admin_x : System.Web.UI.Page, ICommonPostback
- Create properties.
#region Cross page postback var
private int iItemID = -1;
private int iClientUploadID = -1;
public int IItemID
{
get { return iItemID; }
set { iItemID = value; }
}
public int IClientUploadID
{
get { return iClientUploadID; }
set { iClientUploadID = value; }
}
#endregion
This may not be necessary, but I consider it worth the effort to get cleaner code for all pages involved in the posting cycle.
- Create a button on each page with the post back URL set to the other page.
<asp:Button ID="Button1" runat="server" Text="Button"
onclick="Button1_Click" PostBackUrl="~/Admin/y.aspx" />
- Create a
Button_Click
event with the following (given that this is x.aspx). You set the values here to be referenced in the receiving page.
protected void Button1_Click(object sender, EventArgs e)
{
iItemID = 22;
iClientUploadID = 23;
}
On the receiving page (given that this is y.aspx).
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
ICommonPostback frm = PreviousPage as ICommonPostback;
Label1.Text = frm.IItemID.ToString();
}
}
- Do the same on the other page, but change the variables to show that posting has occurred. See the attached code (uses ASP.NET and C# 3.5).
- Note, for master pages, it will work the same, except you will need to reference the
PreviousPage.Master
, or if nested, the master page's PreviousPage.Master.Master
.