Adapter Patterns and Cross Page Post Backs

Monday, July 25, 2005

It was a quiet weekend morning, and I thought I’d write up a quick blog posting with the above title. About 1400 words later, I realized I had zoomed past post length material into article length, so I put Design Considerations for Cross Page Post Backs in ASP.NET 2.0 in the main OdeToCode article area. Excerpt:

It’s also interesting to note the behavior of the PreviousPage property during a cross page post back. PreviousPage uses lazy evaluation, meaning no previous page will exist until the first time you touch the property. At that point the runtime will load a new instance of the PreviousPage web form and have it start to process the current request. This might sound odd at first, but we’ll see why the approach makes sense.


Comments
mike lorengo Monday, July 25, 2005
Well, this is a very timely article for me, I was in the process of writing up a similar entry. What was bugging me is how to execute a cross page postback via codebehind?

I have an instance of a GridView control that functions as a Summary List of Items, I would like to handle the SelectChanged event, and post to a new page to display the detailed view of the selected item.

I was able to use the following in the .aspx
<asp:LinkButton id="nameLinkButton" runat="server" PostBackUrl="ExampleDetail.aspx" CommandName="ExampleDetail" CommandArgument=<%# Eval("Id") %>><%# Eval("Name") %></asp:LinkButton>

but what I really wanted to do was something like this in the codebehind...

protected void ProducerGridView_SelectedIndexChanged(object sender, EventArgs e)
{
// Post to Postback Url
}


Is there a way to do this?

Thanks
scott Monday, July 25, 2005
I'd say once you are on the server, the only options would be to Server.Transfer to the other url, or Response.Redirect. Once you are on the server I don't think there is an easy way to POST to the other page, unless you want to do it programatically with HttpWebRequest, or send the page back to the client with some JavaScript to automatically post back. Know what I mean? It's the client's job to POST, server-side just responds to those requests.
Prasad Thursday, August 4, 2005
Really constructive and well drafted article.Thanks Scott.
scott Thursday, August 4, 2005
Thank you for the feedback, Prasad.
bnair Wednesday, August 17, 2005
I am not sure what is new about the response.redirect method ?
scott Wednesday, August 17, 2005
Nothing new in Response.Redirect really, but I did want to cover all three options.
Raghu Friday, August 26, 2005
Gives good insight into three available options. Adapter patterns does provide good decoupling feature, but is it possible to trace the original page ( since the destination page knows postbackurl) and redirect to it, when the original page is not valid (since asp.net framework creates this page with viewstate load to be processed by destination page).
Mike Vanderkley Saturday, September 3, 2005
Hi Scott

Thank you very much for the article.

I am trying it out in VS 2005 beta 2.

This line of code
IParameterForm form = PreviousPage as IParameterForm;

Has the blue underline saying that i need to set a reference?

I have searched Reflector and Google and cannot find a namespace that removes the error on IParameterForm.

Do you have an idea?

Thank you

Mike
Michael J. Ryan Thursday, September 8, 2005
haven't read the comments, but on the second page override the Render, and if it isn't valid, call the Base.PreRender, then Base.Render, then exit the overridden function.. otherwise, simply render the second page.. :)
Juan Mejia Sunday, March 5, 2006
Well, the new interface move was very good, I was getting a casting problem using not the PreviousPageType directive but the Reference directive, so with this I can handle many source pages, but, I have to implement all the propoerties defined in the the interface for the code to compile, is there a way to "pre-implement" the code in the interface, this is, that only properties I need in certain source page are redifined, and the rest remain default?
BrokenWing Wednesday, March 29, 2006
I have a DataGrid showing a summary of a table. I have a 2 dropdownlists on the page that alter the number of rows returned, the number of rows per page.

The user clicks on a button column in the grid to transfer to an edit page where they can update details. Using the PreviousPage directive I can access the grid page's properties to see which ID they clicked and load the appropriate table row.

On saving the details I want to transfer back from the edit page to the grid page, but here's the rub: I want the grid page to be in the state it was when I selected the row to edit, i.e. same number of rows and rows per page.

In ASP.NET 1.1 I used Server.Transfer and stored the values in the HttpContext before transfer. I then read these values into ViewState properties on the edit page. On saving I did the same to transfer the values back to the grid page.

Using PreviousPage I can transfer values from grid page to edit page but I can't use the same directive to get edit page values on the grid page because I get a "circular reference!" error on compilation.

I'm going to try the decoupling interface approach to get around this, but is there another way to store some of a page's viewstate on a second page in order to restore that viewstate when you return to the page? Preferably with typesafe properties like PreviousPage.

After all these 2 pages will only post to one another. Why am I not allowed this "circuar reference"?
Adam Davsko Tuesday, April 11, 2006
I'm having trouble with cross page post backs and a gridview. I have a column of linkbuttons in the grid, all set up with a PostBackURL property. I have the gridview itself exposed as a public property of my source page, which implements an interface that expects a gridview property. I'm getting an exception in my target page when I click one of the linkbuttons in my grid: "'PreviousPage' threw an exception of type 'System.Threading.ThreadAbortException'". I did some research and this exception is known to be thrown on occasion when doing a response.redirect or a server.tranfer without setting the bool endresponse property to 'false'. This doesn't seem to help me, as I'm doing neither a redirect nor a transfer from the source page.. Help? :) Thanks in advance!
Jeffrey Friday, April 14, 2006
Nice article. But i have got one important question: If i want to use postbackurl at page1 to page2, it's working fine. But when both pages have an masterpage, you don't simply get the controls of page1 into page2.

Before: PreviousPage.FindControl("TB1")
With MasterPage: PreviousPage.Controls[0].Controls[3].Controls[1].FindControl("TB1")

Do you know a solution?
Jeffrey Friday, April 14, 2006
RE--
This problem is solved by using properties. At first it didn't work beceause my masterpage had some usercontrols on it (registers @Page), that gave the problem that the smart intelli didn't see the property. Problem solved!
Sorry for this..
Jeffrey Tuesday, April 18, 2006
New problem when you have 3 pages and what to postbackurl to each other.

Page1: set your property in PageLoad and a button does postbackurl to page2

private string mName;
public string Name
{
get { return mName; }
set { mName = value; }
}

protected void Page_Load(object sender, EventArgs e)
{
mName = "TEST";
}

Page2: gets in PageLoad property of PreviousPage and sets his own property and a button does postbackurl to page3

private string mName2;
public string Name2
{
get { return mName2; }
set { mName2 = value; }
}

protected void Page_Load(object sender, EventArgs e)
{
mName2 = PreviousPage.Name;
}

Page3: gets in PageLoad property, but PreviousPage is Empty! Why? Can somebody explain this to me? (PreviousPage is null)

protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Text = PreviousPage.Name2;
}
scott Tuesday, April 18, 2006
Jeffrey:

In Page 2 when you do this:

mName2 = PreviousPage.Name;

You can have a null PreviousPage when crossposting to Page3, because Page3 will have a PreviousPage but Page2 won't.
Jeffrey Wednesday, April 19, 2006
Scott:

Is there a solution for this problem? Cross postback works fine from the first page to the second page. You can do anything you want. But cross posting from page 2 to page 3, you cannot. It's seems that in page 3 the rebuild of the previousPage doesn't happen. The only thing you can access are the controls on the form and not the properties anymore. Do you know a nice way to solve this problem with crossposting? Maybe my knowledge of this is too little. A solution could be viewstate, server transfer, but i think it should be possible with postbackurl, don't you?
Jeffrey Wednesday, April 19, 2006
Re--

Solution:

public string Name
{
get
{
if (ViewState["param"] != null)
return ViewState["param"].ToString();
else
return "";
}
set { ViewState["param"] = value; }
}

I totaly forgot that you lose your parameter. if you set you parameter in a viewstate, than you can always read this with crosspostback. (Property)
My mistake, but i'm learning.

Jeffrey
scott Wednesday, April 19, 2006
Jeffrey: glad to see you worked that one out!
Harry Thursday, June 1, 2006
I enjoyed reading your article. I have a question that ties into but is not exactly along the lines of your thoughts.

I have a page with data in html hidden fields that must be posted to another web site, not on the same domain, servers, or under my control.

Under asp.net 1.1 I used javascript on set the forms action to the new web site, and the onclick event of the submit button to prepare the form data. This transfered fine. When I upgraded the site to 2.0 This no longer functions. I am not sure how to post this data any longer.

Any ideas?
scott Friday, June 2, 2006
Harry: anychance the form has a runat="server" tag? That's the only thing I can think of that would prevent the form from working.
Harry Monday, June 5, 2006
No, There is no runat tag.

What I have found since I posted is that on some machines it does work fine, but on many it does not. I cannot find any browser settings on the clients that are different.

I was hoping to find a server based solution that would eliminate the problem.
Mario Thursday, June 29, 2006
The code in the article was working great, but once I start using master pages and place the form inside a content place holder I am now not able to reference any objects from the form.

Any suggestions in how to accomplish this inside master pages?
Frits Monday, July 31, 2006
Can't find the interface IParameterForm. Is it something you designed yourself? Your example does not compile.
scott Monday, July 31, 2006
IParameterForm is defined in the article as:

using System;
public interface IParameterForm
{
string ParameterText
{
get;
}
}
Lisa Monday, August 7, 2006
This article has been very helpful, thank you. I am using the interface and server.transfer method with several pages sending parameter data to one page that renders reports and it works great but I have a request to open the target page in a new window. Any ideas on how I might be able to keep the decoupling and send to a new window?
Scott Tuesday, August 8, 2006
Hi Lisa:

I'd embed the parameters in the URL if possible, if not, they'll have to stick around on the server somewhere (session, database).
sbyard Thursday, September 14, 2006
I want to decouple a callback from the original page (i.e. perform a callback, but to another page), but a standard postback goes to the normal page.

Why?

A callback raises many page events (except pre-render for example). It also causes validation to be performed, so if you have a 10 second cyclic client call back for example, the server performs a lot of wasted processing, simply to return a string
Martin Friday, September 15, 2006
Hi

I have created a query form (with Master pages) by adding a User Control.

The User Control has controls added to it dynamically according to the thing you are searching for.

The "Do Query" button has a PostbackUrl to a results page.


When I try to access the User Control on the previous page FindControl returns null and a quick look at the previous page in the watch window shows a very empty User Control.

Does anyone know anything about this?



protected void Page_PreRender(object sender, EventArgs e)
{
poster = this.PreviousPage;

SearchControl sc = (SearchControl)poster.FindControl("SearchControl1");

sc is always null and whatever NamingContainer I use doesn't work either.



Marty
scott Friday, September 15, 2006
Marty:

If you are dynamically loading the user control, you'll have to make sure you dynamically re-load the user control on post back in page_load, otherwise it won't be in the previous page. Remember, the previous page executes on a cross page postback, but only to a certain point.
sergiotarrillo Monday, September 25, 2006
Hi Scott!

Thanks for the article!

Saludos,
Lu5ck Monday, October 9, 2006
Hi Scott,

I got trouble using cross page postback in master pages. I tried creating a bright new website with one master page and 2 content page to it. The 1st content page has only 1 textbox and a button to do the cross postback to 2nd content page. However, the 2nd content page is unable to find the control, why is it so?
---------------------------------------------
Hey jeffy,

May I know what properties did u change?

Thanks all
ricka Tuesday, October 31, 2006
Response.Redirect and Server.Transfer should both be considered obsolete because they throw. When it comes time to fix a real problem on your site you're SPAMMED with the exceptions they throw.

Response.Redirect is also very expensive.
ricka Tuesday, October 31, 2006
Oops, forgot to mention - EXCELLENT work!
gravatar Mani Saturday, October 17, 2009
Got many insights of various techniques, Thank You Scott Allen
Pradeep Friday, January 15, 2010
Nice Article,
Enjoyed reading it. Just wanted to add a small comment for those who are still wondering why the Server.Transfer is not working for them. Please implement the IParameterForm interface in your source page and return the value you need to send across to the Target page.
Cheers!!
Pradeep
w00te Friday, February 19, 2010
Hey,

I just wanted to say thanks for this article. I'm extremely well versed in C#, but I'm currently learning ASP and extracting data from the PreviousPage property after a crosspage postback was making me want to jump off a cliff.

Dealing with the non-persistance of webpages vs the persistant nature of console programming is really a hard thing to get used to.

Anyway! In short, keep it up and thank you very much for the help.
w00te Friday, February 19, 2010
Hey,

I just wanted to say thanks for this article. I'm extremely well versed in C#, but I'm currently learning ASP and extracting data from the PreviousPage property after a crosspage postback was making me want to jump off a cliff.

Dealing with the non-persistance of webpages vs the persistant nature of console programming is really a hard thing to get used to.

Anyway! In short, keep it up and thank you very much for the help.
gravatar hongjun Friday, February 4, 2011
>>If you are dynamically loading the user control, you'll have to make sure you dynamically re-load the user control on post back in page_load

Hi Scott,

How do we re-load since it is already loaded?
gravatar scott Monday, February 7, 2011
This is talking about explicit loading with LoadControl method...
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!