My Page Just Had Deja Vu
One function whose absence I find annoying in ASP.NET is the ability to easily return to a previous page and reload its state. I recently needed this functionality in a project for a course registration application I was building at work.
The basic scenario is this:
- User enters some search criteria on the Course Search page and a list of matching courses is returned.
- The user selects a course and is directed to the Student Roster page for that course.
- The user then selects a particular student and is directed to the Student Maintenance page.
Now, the user will almost always need to get back to the Student Roster page, and maybe even the Course Search page after making changes on the Student Maintenance page. However, they don’t want to start the whole process over back at Course Search each time.
So, I tried a number of ways to accomplish this in a generic fashion, the first being a convoluted method using the PageStatePersister class to pop the page’s ViewState into Session and bring it back when the user returns. However, this can be problematic because the page is unaware of what’s going on in the application outside of itself. In other words, data may have changed or the user may have returned to this page through a non-linear route and now needs a different set of criteria; they don’t want the same options they chose before.
So what I came up with was a simple solution using the query string and a ReturnUrl parameter. I’m sure we’ve all seen these things gumming up query strings around the web. While it does tend to make your URL rather intense, it is an effective method and it’s easy to see what’s going on. So here are the requirements I set up for whatever method would implement this functionality:
- The method must be able to pass forward a ReturnUrl parameter which can hold both control values on the original page as well as any query string variables which were passed to it.
- The method must be able to handle n forward progressions and likewise be able to link backwards n times without losing anything along the way.
- When a page reloads from a ReturnUrl the method must be able to set values on ASP.NET WebControls on Page_Load.
So, I wrote a class which inherits from System.Web.UI.Page called DejaVuPage (an apt name I thought) which encapsulates this functionality. The code for this class can be found in the App_Code folder in the zip file which accompanies this post as DejaVuPage.cs. Essentially, there are four things any page inheriting from DejaVuPage can now do:
- Set a list of controls to be included in potential ReturnUrl params. This is done by adding control IDs to the DejaVuPage.ReloadableControls (ArrayList) property.
- At any time get what the current ReturnUrl parameter would be. This is done by getting the DejaVuPage.ReturnUrl property.
- Redirect to the previous page by calling this.RedirectToReturnUrl().
- Reload a page's controls from a ReturnUrl by calling this.LoadFromReturnUrl().
The ASP.NET sample project included in the post has a good example; run the app, enter some criteria on each page, then when you get to the end use the ‘Go Back’ links each previous page will reload it’s controls as you left them before.
I’m sure someone can improve my code, so if you see somewhere where this concept could be refined, please let me know. I hope some of you find this useful.