ASP.NET Futures (July 2007): Managing Browser History and Back Button Support in ASP.NET AJAX
This section provides information about the following features::
- History and bookmarking. You can manage history points in your application,
which lets users click the browser's Back and Forward buttons to navigate logically
through your application instead of browsing to other pages.
- The
History server control. This control lets you manage application history
and use the Navigate event in the server and client.
- The client
Sys.Application object. This object lets you set history points.
It also calls the pageNavigate function.
ASP.NET Futures (July 2007) release The following changes and additions have been introduced:
- History is now supported for the Apple Safari browser.
- Any state that is provided through the server is encoded and can be encrypted.
- You can define titles for individual history entries to be able to specify the page title used in the browser's history list.
- You can use history support entirely in the client, without the need for a server control.
An inherent problem with AJAX-style applications is browser navigation. Because
an AJAX-style page can interact with the server by using asynchronous postbacks,
users can perform many tasks without leaving the page. However, if users click the
browser's Back button, by default the browser does not return to a previous state of the page (for
example, the state before the most recent asynchronous postback). Instead, the browser unloads
the page entirely and returns to the page that was displayed before your page was
started. Very frequently, this is not what the user intended.
You can manage history (Back and Forward button navigation) to provide a more logical and
natural navigation model in your Web application. As the page developer, you control the
state that is required to recreate the page. You can manage history navigation in both server and
client code. You do this by defining points in your application that act like bookmarks that users return to
when they navigate with the Back and Forward buttons.
Security Note: History state from the server is encoded. If viewstate
is configured for encryption, server-based history state is encrypted as well. State
from the client is encoded. This means that a malicious user could read and potentially
modify client history state. (The server state cannot be tampered with if it is
encrypted.) You should treat history state like user input and take appropriate precautions
to safeguard against security issues. You should never put sensitive
data in either server-based or client-based history state.
History Management with Server Controls
|
Top |
Server-based history management is provided by the History Web server control.
This control enables you to handle server events as you normally do in postback
scenarios and to set a history point on the control. At the history point you define
an object or data (that is, state) that will be used to recreate your page when
a navigation event is raised. When you create history points, the page's URL is
appended with the serialized and encrypted data that is required to recreate the state of the page. This
also creates an entry in the browser's history stack.
When users click the browser's Back button, the browser navigates through previously-viewed
URLs, which will include URLs that contain history-point data. A Navigate event
is raised for the History control; the event data includes the data
appended to the URL. This enables you to handle the event and recreate the page
state as required in your application.
The following example uses the UpdatePanel control for asynchronous
postbacks. The History control is used to add history points during
the Click event handler of the buttons that trigger the asynchronous
postbacks. As a result, when you click the browser's Back button, you do not leave
the Web page, but instead navigate through the previous UpdatePanel
postbacks.
Controlling navigation with the History control
<script runat="server">
..
// Handle the Navigate event and set data. This is raised when URL data is available.
public void OnNavigate(object sender, HistoryEventArgs args) {
l.Text = (args.State.ContainsKey(PageStateKey)) ? args.State[PageStateKey].ToString() :
String.Empty;
}
// On button click, handle the event in server code and set a history
// point, passing some state to recreate the page during navigation.
public void ButtonClick(object sender, EventArgs args) {
int state = int.Parse(((Button)sender).Text, CultureInfo.InvariantCulture);
l.Text = state.ToString();
History1.AddHistoryPoint(PageStateKey, state);
}
</script>
..
<asp:History runat="server" ID="History1" OnNavigate="OnNavigate" />
C#
Client History Management
|
Top |
You can also write JavaScript code to manage history navigation. For example, you
might use client objects to provide rich behavior (such as opening a collapsible
panel) and set history points to provide navigation through the state of the page.
The following example shows how you can manage history points in the browser. You
set a history point by using the Sys.Application class and defining
state for that history point. You can then implement the pageNavigate
function that is called when the page is navigated. This function is called just
before the pageLoad function in the initial GET request. It is also
called whenever the user clicks the browser's Back or Forward button, and during
the PageRequestManager.endRequest event in asynhrchronous postbacks.
You can manage history by simply using the pageNavigate
function. But you can also attach a handler to the Sys.Application navigate
event by calling the Sys.Application.get_history().add_navigate() method.
Managing history in the client
<script type="text/javascript">
function pageNavigate(sender, args) {
// When the page is navigated, this event is raised.
// Recreate the page for a given state.
var val = args.get_state().pageClientState || 0;
$get("div2").innerHTML = val;
}
function clientClick(e) {
// Set a history point in the client.
var val = parseInt(e.target.value);
$get("div2").innerHTML = val;
Sys.Application.get_history().addHistoryPoint({pageClientState: val});
}
</script>
..
<asp:ScriptManager runat="server" ID="ScriptManager1" />
<asp:History runat="server" ID="History1" />
..
JavaScript
Enabling Permalinks to Page State
|
Top |
You can enable users to set a permalink to a specific state of the page. This means
that they can bookmark a particular point in your application and then set the page with that
state as a favorite or email the permalink URL so that the specific page state can be recreated.
To enable users to create a permalink, you can get the current state by using the
Sys.Application.get_history().get_stateString() in client script, and
History.getStateString() in server code. The following example shows how to
create a permalink for a specific state through client-side JavaScript code.
Creating permalinks from history state
Managing the Title of a History Entry
|
Top |
Typically, entries in the browser's history stack are identified by the title of
the page for that entry. (To see an example of this, use the browser's recent-pages drop-down list
to view the titles.) By default, when you create history entries in your application as described previously,
the page's title is used to identify a history-state entry. However, you can provide
meaningful titles for individual history entries. The following sample shows how to
perform this task. In the client, add a title parameter when you call the
Sys.Application.get_history().addHistoryPoint( ) method. In server code,
you can add a title when you call the History.AddHistoryPoint( ) method.
<script type="text/javascript">
..
function clientClick(e) {
// Set a history point on the client and define the title.
var val = parseInt(e.target.value);
$get("div2").innerHTML = val;
Sys.Application.get_history().addHistoryPoint({pageClientState: val}, "The title");
}
</script>
..
<asp:ScriptManager runat="server" ID="ScriptManager1" />
<asp:History runat="server" ID="History1" />
..
JavaScript
The following example shows how to set titles in both client and server code.
Managing titles for history-state entries
|