AJAX History

Browser History and the Back Button with ASP.NET AJAX

Don Kiely

October 30, 2009

6 Min Read
ITPro Today logo in a gray background | ITPro Today

Exploring ASP.NET & Web Development

 

AJAX History

Browser History and the Back Button with ASP.NET AJAX

 

By Don Kiely

 

One of the problems with ASP.NET AJAX and, in fact, mostall AJAX implementations is that the browser s back and forward buttons do notstore the history of page state for AJAX requests. A browser goes only by URLs,and because the page address doesn t change when something causes an AJAXrequest, nothing is saved in the browser s history cache. Only when the usernavigates to another page is history updated with the new page.

 

Microsoft provided a solution to the problem in servicepack 1 for Visual Studio 2008 and the .NET Framework 3.5: AJAX History. Irecently had the opportunity to explore this feature for ASP.NET 3.5 coursewareI wrote for AppDev with Ken Getz; this article is based on that work.

 

AJAX History isn t enabled by default, and takes a littlework to implement but it can greatly enhance users experience as they browseyour site. The hardest part is deciding how to implement this feature in a waythat makes sense for the user, given the set of controls on the page that areenabled with AJAX.

 

For example, say you have a page based on the Northwinddatabase that displays a dropdown list with product categories. As the userselects different categories, the list of products in the selected categoryappears in a grid, which is wrapped up in an AJAX UpdatePanel. This makes theuser interface smoother, with no page flashing but doesn t give the browserunique URLs to store in history. It is fairly easy to decide how to use historyfor the sample application. Each time the user selects a new product category,that page state should become a history point. A history point is saved statethat you can navigate back to. Implementing history requires changes to thepage (and some code).

 

You have to make a few changes to the ScriptManagercontrol to implement AJAX History. You have to explicitly enable history bysetting the EnableHistory attribute to true. You also have to supply a methodfor the onnavigate event that fires when the user navigates between pages. (I lldiscuss the EnableSecureHistoryState attribute shortly.) The following codeshows the ScriptManager definition in ProductsHistory.aspx:

 

 EnableHistory="true"  EnableSecureHistoryState="false"  onnavigate="ScriptManager1_Navigate">

 

The other change needed in the page is to place thedropdownlist and its data source into the UpdatePanel. In the non-AJAX versionof the page, these controls are located outside the UpdatePanel because theydon t have to be updated as part of the AJAX request. In this new version ofthe page, with history enabled, the code has to change the state of thedropdownlist to return the page to a previous state, so the controls must bewithin the UpdatePanel.

 

The code behind the page needs two methods to implementAJAX History. The first method saves a history point in response to a newcategory selection by the user. The code starts by checking to see whether thepage is in the midst of an asynchronous postback an AJAX request and makessure that the user is not navigating to another page. If it is not an AJAXrequest and the user is navigating, you don t want to save the state.

 

If it meets these conditions, the code then creates aunique title for the page, concatenating the Northwind Products string withthe name of the category. This is a good practice both so that the page titlebar displays a meaningful title and because this will become the titledisplayed in the browser history, making it easy for the user to select aprevious page state.

 

Then the code creates the history point using theScriptManager s AddHistoryPoint method. This method has a few overloads, butthe one used here passes a name for the query string parameter, the selectedindex in the categories dropdownlist, and the same page title created earlierin the code. This method saves the state by generating a unique query stringthat the browser can add to its history.

 

Following is the complete C# code for the list sSelectedIndexChanged event:

 

if (ScriptManager1.IsInAsyncPostBack

&& !ScriptManager1.IsNavigating)

{

string title = "Northwind Products: "

+ DropDownList1.SelectedItem.Text;

Page.Title = title;

ScriptManager1.AddHistoryPoint("category",

DropDownList1.SelectedIndex.ToString(),

title);

}

 

The state that you save with the AddHistoryPoint method isup to you. It needs to be enough to return the page to that previous state, nomatter what the user has done in the meantime. The decision of how to definethis state can take some hard thinking, depending on how a page operates.

 

The second method required to implement AJAX History is torespond to the ScriptManager s Navigate event. This event fires when the useris navigating to an item in the browser history list, passing in aHistoryEventArgs object that contains the state it reads from the query stringparameter.

 

The code reads the state and checks to see if it is nullor empty. If it is null or empty, it sets the selected index value to the firstitem in the list (zero). If state is available, it sets the selected index ofthe dropdownlist to the saved value, which causes the products for thatcategory to reload. Following is the complete code for the ScriptManager sNavigate event:

 

string indexStr = e.State["category"];

if (string.IsNullOrEmpty(indexStr))

DropDownList1.SelectedIndex = 0;

else

{

int index = Convert.ToInt32(indexStr);

DropDownList1.SelectedIndex = index;

}

 

Now when the user selects different categories, ASP.NETgenerates a unique URL that the browser can save in history to return to aparticular AJAX state. The URL looks something like this, with ASP.NET addingthe query string parameter based on the code you wrote:

 

http://localhost:1414/Extensions/ProductsHistory.aspx#&&category=3

 

There is one potential problem with how the page isimplemented: State information is visible to the user in the URL in thecategory query string value. This could be a security problem, so, by default,ASP.NET encrypts the query string value. You can control this with theEnableSecureHistoryState attribute of the ScriptManager control, which is setto true by default. Set to true, you ll find that the URLs now look somethinglike this:

 

http://localhost:1414/Extensions/ProductsHistory.aspx#&&DwIbkbGQcKwH0/g6B9ZXDjIOj2fmQbuiHhPet+8qFRY=

 

Used where appropriate, AJAX History can make pages muchmore usable for users, making it easier to return to different versions duringa single session. Users also can bookmark various page states, making it easierto return to them later.

 

Don Kiely, MVP,MCSD, is a senior technology consultant, building custom applications as wellas providing business and technology consulting services. His development workinvolves tools such as SQL Server, Visual Basic, C#, ASP.NET,and Microsoft Office. He writes regularly for several trade journals, andtrains developers in database and .NETtechnologies. You can reach Don at mailto:[email protected]and read his blog at http://www.sqljunkies.com/weblog/donkiely/.

 

 

 

 

Read more about:

Microsoft
Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like