ASP.NET サーバー コントロールを使用するブラウザ履歴の管理
更新 : 2007 年 11 月
ページ作成者は、ScriptManager サーバー コントロールおよび ScriptManagerProxy サーバー コントロールを使用して、ブラウザ履歴のエントリを管理し、論理的なナビゲーションを提供できます。ScriptManager サーバー コントロールを使用して、アプリケーションに履歴ポイントを設定できます。両方のコントロールを使用することで、履歴状態の結果として Web ページが要求されるときに発生するナビゲーションを処理できます。
履歴ポイントは、Web アプリケーション内の論理的なナビゲーション ポイントであり、状態情報によって表すことができます。状態情報を使用して、Web アプリケーションを前の状態に戻すことができます。状態データは、直接操作するか、他の場所に保存されている状態情報を示す識別子をとおして操作できます。
履歴ポイントは、ブラウザの履歴スタックに URL 形式でのみ保存されます。履歴の状態は、クエリ文字列内のデータとして、または "#" 文字でマークされた URL フラグメント値として管理されます。URL にはサイズの制限があるため、状態情報はできる限り短く作成する必要があります。状態を示すのに十分な長さの履歴ポイント データを含む URL を次の例に示します。この情報を基にアプリケーションではページをこの状態で再作成できます。
http://MySamples/Ajax/Default.aspx#&&state=2
ブラウザの [戻る] ボタンをクリックすると、前に表示されていた URL に表示が移動します。この URL に履歴ポイントの状態を示す URL が含まれます。Web ページ内のクライアント コードでは、URL に履歴状態データが含まれることが検出され、要求がそのページに送られ、状態情報が渡されます。ページでは、要求を処理する過程で履歴状態情報を読み取り、非同期ポストバックを生成します。ScriptManager サーバー コントロールおよび ScriptManagerProxy サーバー コントロールは、Navigate イベントを生成します。このイベントを処理して、Web アプリケーションに必要なページを再作成できます。
メモ : |
---|
このトピックのサンプル コードを作成するには、Visual Studio 2008 Service Pack 1 以降のバージョンが必要です。 |
ScriptManager および ScriptManagerProxy コントロールの構文
ブラウザ履歴を操作するための ScriptManager サーバー コントロールの構文を次の例に示します。
<asp:ScriptManager runat="server"
EnableHistory="true|false"
EnableStateHash="true|false"
OnNavigate="navigateEventhandlerName">
</asp:ScriptManager>
ブラウザ履歴の管理を有効にする
履歴の管理を使用するには、ScriptManager サーバー コントロールを使用して、この機能を有効にする必要があります。既定では、履歴サポートは無効になっています。履歴を有効にする場合、この機能はブラウザによって異なる方法で実装されます。Internet Explorer の場合、iframe 要素がブラウザにレンダリングされます。これにより、サーバーへの要求が追加されることがあります。したがって、このモデルはオプトイン方式です。ScriptManager コントロールを使用して、履歴を宣言によって有効にする例を次に示します。
<asp:ScriptManager runat="server" ID="ScriptManager1"
EnableHistory="true" />
ブラウザ履歴ポイントを作成する
ブラウザ履歴ポイントを作成するには、ScriptManager コントロールの AddHistoryPoint メソッドを呼び出します。このメソッドを使用して、サーバーの状態およびキーを定義し、ブラウザの履歴エントリのタイトルを表すオプション データを指定できます。後で履歴ナビゲーション イベントが発生したときに、状態データを使用してページの状態を再作成できます。既定では、履歴ポイントを作成すると、シリアル化および暗号化されたデータが Web ページの URL に追加されます。生成された URL は、ブラウザの履歴スタックに格納されます。
メモ : |
---|
選択項目をクリックするなどのユーザーの操作に対する応答としてのみ、履歴ポイントを追加します。通常、履歴ポイントは、アプリケーション コードの実行によって追加されません。 |
次の例では、UpdatePanel コントロールを使用してページの非同期ポストバックを有効にする方法を示します。ScriptManager コントロールは、非同期ポストバックを生成するボタンの Click イベント ハンドラ内で履歴ポイントを追加するために使用されます。ブラウザの [戻る] をクリックすると、Web ページから移動せずに、そのページの前の履歴状態に従って移動します。
この機能のサンプルを実行してください。
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Private Shared key As String = "s"
' Handle the Navigate event
Public Sub OnNavigateHistory(ByVal sender As Object, ByVal e As HistoryEventArgs)
LabelHistoryData.Text = Server.HtmlEncode(e.State(key))
End Sub
' On button click, handle the event and set a history point.
Public Sub ButtonClick(ByVal sender As Object, ByVal e As EventArgs)
LabelHistoryData.Text = CType(sender, Button).Text
ScriptManager.GetCurrent(Me).AddHistoryPoint(key, LabelHistoryData.Text)
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Microsoft ASP.NET 3.5 Extensions: Managing History</title>
<link href="../../include/qsstyle.css" type="text/css" rel="Stylesheet" />
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" OnNavigate="OnNavigateHistory"
EnableHistory="true" EnableSecureHistoryState="false" />
<h2>
Microsoft ASP.NET 3.5 Extensions: Adding Server-side Browser History Points</h2>
<p/>
<div id="Div1" class="new">
<p>This sample shows:</p>
<ol>
<li>How to use the <code>ScriptManager</code> control to set a history point.</li>
<li>The <code>ScriptManager</code> control, the <code>EnableHistory</code> and
<code>EnableSecureHistoryState</code> properties and
the <code>OnNavigate</code> property to handle the <code>navigate</code>event.<br />
</li>
</ol>
</div>
<p>
In this example, three buttons outside the <code>UpdatePanel</code> control can
trigger an asynchronous postback. You can see the results of the update through
the date and time that renders in the Web page along with a value indicating the
button that triggered the partial refresh.</p>
<p>
When you press a button, the server-side <code>Click</code> event handler for the button
stores data and uses the data as a history point. If you click the browser's Back button,
you will see the state Web page return to a previous button value, representing the previous
button you pressed. However, you will see that the time within the Web page continues to be
incremented.
</p>
<p>To see the effect of this logic, do the following.</p>
<ol>
<li>Press <b>1</b>. See the panel refresh.</li>
<li>Press <b>3</b>. See the panel refresh.</li>
<li>Press <b>2</b>. See the panel refresh.</li>
<li>Press the browser's Back button. Note that the panel is refreshed with previous
data, but the date and time are updated to current values.</li>
</ol>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button3" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Panel runat="server" CssClass="box" ID="Content" Height="40px">
Date and Time:
<%= DateTime.Now.ToLongTimeString() %>
<br />
Page's refresh state:
<asp:Label runat="server" ID="LabelHistoryData" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<p />
<asp:Button runat="server" ID="Button1" Text="Key 1" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button2" Text="Key 2" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button3" Text="Key 3" OnClick="ButtonClick" />
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
private static String key = "s";
// Handle the Navigate event
public void OnNavigateHistory(object sender, HistoryEventArgs e) {
LabelHistoryData.Text = Server.HtmlEncode(e.State[key]);
}
// On button click, handle the event and set a history point.
public void ButtonClick(object sender, EventArgs e) {
LabelHistoryData.Text = ((Button)sender).Text;
ScriptManager.GetCurrent(this).AddHistoryPoint(key, LabelHistoryData.Text);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Microsoft ASP.NET 3.5 Extensions: Managing History</title>
<link href="../../include/qsstyle.css" type="text/css" rel="Stylesheet" />
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" OnNavigate="OnNavigateHistory"
EnableHistory="true" EnableSecureHistoryState="false" />
<h2>
Microsoft ASP.NET 3.5 Extensions: Adding Server-side Browser History Points</h2>
<p/>
<div id="Div1" class="new">
<p>This sample shows:</p>
<ol>
<li>How to use the <code>ScriptManager</code> control to set a history point.</li>
<li>The <code>ScriptManager</code> control, the <code>EnableHistory</code> and
<code>EnableSecureHistoryState</code> properties and
the <code>OnNavigate</code> property to handle the <code>navigate</code>event.<br />
</li>
</ol>
</div>
<p>
In this example, three buttons outside the <code>UpdatePanel</code> control can
trigger an asynchronous postback. You can see the results of the update through
the date and time that renders in the Web page along with a value indicating the
button that triggered the partial refresh.</p>
<p>
When you press a button, the server-side <code>Click</code> event handler for the button
stores data and uses the data as a history point. If you click the browser's Back button,
you will see the state Web page return to a previous button value, representing the previous
button you pressed. However, you will see that the time within the Web page continues to be
incremented.
</p>
<p>To see the effect of this logic, do the following.</p>
<ol>
<li>Press <b>1</b>. See the panel refresh.</li>
<li>Press <b>3</b>. See the panel refresh.</li>
<li>Press <b>2</b>. See the panel refresh.</li>
<li>Press the browser's Back button. Note that the panel is refreshed with previous
data, but the date and time are updated to current values.</li>
</ol>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button3" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Panel runat="server" CssClass="box" ID="Content" Height="40px">
Date and Time:
<%= DateTime.Now.ToLongTimeString() %>
<br />
Page's refresh state:
<asp:Label runat="server" ID="LabelHistoryData" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<p />
<asp:Button runat="server" ID="Button1" Text="Key 1" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button2" Text="Key 2" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button3" Text="Key 3" OnClick="ButtonClick" />
</div>
</form>
</body>
</html>
サーバーへの要求の処理
サーバー状態が要求内に検出されると、Navigate イベントが発生します。これは、サーバーへの非同期ポストバックのように見えます。ポストバックがナビゲーションまたはその他の目的で生成されたのかどうかを確認するには、IsNavigating プロパティの値を読み取ります。このプロパティが true に設定されている場合は、ポストバックはナビゲーション呼び出しによって生成されたものです。
UpdatePanel コントロール内の Wizard サーバー コントロールを次の例に示します。これによって、ウィザード内を移動すると Wizard コントロールによって非同期ポストバックが実行されます。この例では、ウィザードの手順間を移動するとコードによって履歴ポイントが追加されます。
この機能のサンプルを実行してください。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Private Shared stepKey As String = "s"
Protected Sub OnNavigateHistory(ByVal sender As Object, ByVal args As HistoryEventArgs)
Dim stateString As String = args.State(stepKey)
Dim [step] As Integer = If(stateString IsNot Nothing, Integer.Parse(stateString), 0)
MachineConfiguratorWizard.ActiveStepIndex = [step]
End Sub
Protected Sub OnActiveStepChanged(ByVal sender As Object, ByVal e As EventArgs)
If Not ScriptManager1.IsNavigating AndAlso IsPostBack Then
Dim index As Integer = MachineConfiguratorWizard.ActiveStepIndex
ScriptManager1.AddHistoryPoint(stepKey, index.ToString(), "Step " + (index + 1).ToString())
End If
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Microsoft ASP.NET 3.5 Extensions: Managing History</title>
<link href="../../include/qsstyle.css" type="text/css" rel="Stylesheet" />
</head>
<body>
<div>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" OnNavigate="OnNavigateHistory"
EnableHistory="true" EnableSecureHistoryState="false" />
<h2>
Microsoft ASP.NET 3.5 Extensions: Adding Server-side Browser History Points</h2>
<p/>
<div id="Div1" class="new">
<p>This sample shows:</p>
<ol>
<li>How to use the <code>ScriptManager</code> control to set a history point.</li>
<li>The <code>ScriptManager</code> control, the <code>EnableHistory</code> and
<code>EnableSecureHistoryState</code> properties and
the <code>OnNavigate</code> property to handle the <code>navigate</code> event.
</li>
<li>Protecting the history code with <code>IsNavigating</code>
</li>
</ol>
</div>
<p>
In this example, the <code>Wizard</code> server control provides it's own navigation, but
as each step is selected a history point is added. In order to do this, a history point is only added if the page is not being refreshed beacuse of a history point.</p>
<asp:UpdatePanel runat="server" ID="WizardPanel">
<ContentTemplate>
<asp:Wizard ID="MachineConfiguratorWizard" runat="server" ActiveStepIndex="0" BackColor="#dddddd"
BorderWidth="10" CellPadding="10" CellSpacing="10" Height="200px" Width="700px"
FinishPreviousButtonText="<" StartNextButtonText=">" StepNextButtonText=">" StepPreviousButtonText="<"
FinishCompleteButtonText="<|>" OnActiveStepChanged="OnActiveStepChanged">
<WizardSteps>
<asp:WizardStep ID="Step1" runat="server" Title="Step 1">
<h2>
STEP 1</h2>
<br />
</asp:WizardStep>
<asp:WizardStep ID="Step2" runat="server" Title="Step 2">
<h2>
STEP 2</h2>
<br />
</asp:WizardStep>
<asp:WizardStep ID="Step3" runat="server" Title="Step 3">
<h2>
STEP 3</h2>
<br />
</asp:WizardStep>
</WizardSteps>
<StepStyle Font-Names="tahoma" Font-Size="Smaller" VerticalAlign="Top" />
<SideBarStyle Font-Size="Small" VerticalAlign="Top" BackColor="#FFFFC0" Font-Names="tahoma" />
<FinishPreviousButtonStyle BackColor="White" BorderColor="Black" BorderWidth="3px"
Font-Names="Tahoma" Font-Size="Medium" />
<NavigationButtonStyle BackColor="White" BorderColor="Black" BorderStyle="Solid"
BorderWidth="3px" Font-Names="Tahoma" Font-Size="Medium" />
<FinishCompleteButtonStyle Font-Names="Tahoma" Font-Size="Medium" />
</asp:Wizard>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
private static readonly string stepKey = "s";
protected void OnNavigateHistory(object sender, HistoryEventArgs args)
{
string stateString = args.State[stepKey];
int step = (stateString != null) ? int.Parse(stateString) : 0;
MachineConfiguratorWizard.ActiveStepIndex = step;
}
protected void OnActiveStepChanged(object sender, EventArgs e)
{
if (!ScriptManager1.IsNavigating && IsPostBack) {
int index = MachineConfiguratorWizard.ActiveStepIndex;
ScriptManager1.AddHistoryPoint(stepKey, index.ToString(), "Step " + (index+1).ToString());
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Microsoft ASP.NET 3.5 Extensions: Managing History</title>
<link href="../../include/qsstyle.css" type="text/css" rel="Stylesheet" />
</head>
<body>
<div>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" OnNavigate="OnNavigateHistory"
EnableHistory="true" EnableSecureHistoryState="false" />
<h2>
Microsoft ASP.NET 3.5 Extensions: Adding Server-side Browser History Points</h2>
<p/>
<div id="Div1" class="new">
<p>This sample shows:</p>
<ol>
<li>How to use the <code>ScriptManager</code> control to set a history point.</li>
<li>The <code>ScriptManager</code> control, the <code>EnableHistory</code> and
<code>EnableSecureHistoryState</code> properties and
the <code>OnNavigate</code> property to handle the <code>navigate</code> event.
</li>
<li>Protecting the history code with <code>IsNavigating</code>
</li>
</ol>
</div>
<p>
In this example, the <code>Wizard</code> server control provides it's own navigation, but
as each step is selected a history point is added. In order to do this, a history point is only added if the page is not being refreshed beacuse of a history point.</p>
<asp:UpdatePanel runat="server" ID="WizardPanel">
<ContentTemplate>
<asp:Wizard ID="MachineConfiguratorWizard" runat="server" ActiveStepIndex="0" BackColor="#dddddd"
BorderWidth="10" CellPadding="10" CellSpacing="10" Height="200px" Width="700px"
FinishPreviousButtonText="<" StartNextButtonText=">" StepNextButtonText=">" StepPreviousButtonText="<"
FinishCompleteButtonText="<|>" OnActiveStepChanged="OnActiveStepChanged">
<WizardSteps>
<asp:WizardStep ID="Step1" runat="server" Title="Step 1">
<h2>
STEP 1</h2>
<br />
</asp:WizardStep>
<asp:WizardStep ID="Step2" runat="server" Title="Step 2">
<h2>
STEP 2</h2>
<br />
</asp:WizardStep>
<asp:WizardStep ID="Step3" runat="server" Title="Step 3">
<h2>
STEP 3</h2>
<br />
</asp:WizardStep>
</WizardSteps>
<StepStyle Font-Names="tahoma" Font-Size="Smaller" VerticalAlign="Top" />
<SideBarStyle Font-Size="Small" VerticalAlign="Top" BackColor="#FFFFC0" Font-Names="tahoma" />
<FinishPreviousButtonStyle BackColor="White" BorderColor="Black" BorderWidth="3px"
Font-Names="Tahoma" Font-Size="Medium" />
<NavigationButtonStyle BackColor="White" BorderColor="Black" BorderStyle="Solid"
BorderWidth="3px" Font-Names="Tahoma" Font-Size="Medium" />
<FinishCompleteButtonStyle Font-Names="Tahoma" Font-Size="Medium" />
</asp:Wizard>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
URL とサーバー履歴状態
ブラウザ履歴ポイントを作成するときには、履歴ポイントの状態に保存する情報を決めます。少なくとも、状態をアプリケーションに示すキーと値のペアを使用する必要があります。その他のキーと値のペアを保存することもできます。ただし、この情報は URL に保存され、URL にはブラウザで決められたサイズの制限があるため、状態を再作成するために必要な情報のみを保存してください。
ScriptManager サーバー コントロールの EnableHistory プロパティに定義した設定によって、ハッシュされた形式またはハッシュされない形式で URL にサーバー状態情報を格納できます。
URL 内の履歴状態は、# 文字 (フラグメントの区切り記号) で区切ります。状態情報は、以下の例のように "&&" 区切り記号の後に指定します。
Default.aspx#&&s=Key+2
EnableHistory を true に設定すると、履歴情報フラグメントは暗号化されてから Web ページの URL に追加されます。これにより、攻撃者が状態データを変更することが難しくなるため、セキュリティが向上します。ただし、情報が暗号化されるからといって、機密情報を状態フィールドに格納しないでください。
状態情報をハッシュ化すると、URL が長くなり、ユーザーにとって意味をなさない情報が追加されます。
履歴ポイントにタイトルを追加する
通常、ブラウザの履歴スタックのエントリは、そのエントリがあるページのタイトルで識別されます。この例を確認するには、ブラウザの履歴リストを使用して、最近開いたページのタイトルを表示します (一般に、このリストは、URL アドレス ボックスのドロップダウン リストを使用して表示できます)。
既定では、履歴ポイント エントリをアプリケーションに作成するときに、そのエントリを識別するためにページのタイトルを使用します。同じページで複数の履歴ポイントを追加しても、既定ではすべてのエントリは同じタイトルになります。
ただし、履歴エントリに個別に意味のあるタイトルを設定することができます。サーバー コードでは、AddHistoryPoint メソッドを呼び出して履歴ポイントを作成するときにタイトル情報を指定できます。
前の例にタイトル エントリを追加した例を次に示します。
この機能のサンプルを実行してください。
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Private Shared key As String = "s"
' Handle the Navigate event
Public Sub OnNavigateHistory(ByVal sender As Object, ByVal e As HistoryEventArgs)
LabelHistoryData.Text = Server.HtmlEncode(e.State(key))
End Sub
' On button click, handle the event and set a history point.
Public Sub ButtonClick(ByVal sender As Object, ByVal e As EventArgs)
LabelHistoryData.Text = CType(sender, Button).Text
ScriptManager.GetCurrent(Me).AddHistoryPoint(key, LabelHistoryData.Text, "Entry: " + LabelHistoryData.Text)
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Microsoft ASP.NET 3.5 Extensions: Managing History</title>
<link href="../../include/qsstyle.css" type="text/css" rel="Stylesheet" />
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" OnNavigate="OnNavigateHistory"
EnableHistory="true" EnableSecureHistoryState="false" />
<h2>
Microsoft ASP.NET 3.5 Extensions: Adding Server-side Browser History Points</h2>
<p/>
<div id="Div1" class="new">
<p>This sample shows:</p>
<ol>
<li>How to use the <code>ScriptManager</code> control to set a history point.</li>
<li>The <code>ScriptManager</code> control, the <code>EnableHistory</code> and
<code>EnableSecureHistoryState</code> properties and
the <code>OnNavigate</code> property to handle the <code>navigate</code>event.<br />
</li>
</ol>
</div>
<p>
In this example, three buttons outside the <code>UpdatePanel</code> control can
trigger an asynchronous postback. You can see the results of the update through
the date and time that renders in the Web page along with a value indicating the
button that triggered the partial refresh.</p>
<p>
When you press a button, the server-side <code>Click</code> event handler for the button
stores data and uses the data as a history point. If you click the browser's Back button,
you will see the state Web page return to a previous button value, representing the previous
button you pressed. However, you will see that the time within the Web page continues to be
incremented.
</p>
<p>To see the effect of this logic, do the following.</p>
<ol>
<li>Press <b>1</b>. See the panel refresh.</li>
<li>Press <b>3</b>. See the panel refresh.</li>
<li>Press <b>2</b>. See the panel refresh.</li>
<li>Press the browser's Back button. Note that the panel is refreshed with previous
data, but the date and time are updated to current values.</li>
</ol>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button3" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Panel runat="server" CssClass="box" ID="Content" Height="40px">
Date and Time:
<%= DateTime.Now.ToLongTimeString() %>
<br />
Page's refresh state:
<asp:Label runat="server" ID="LabelHistoryData" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<p />
<asp:Button runat="server" ID="Button1" Text="Key 1" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button2" Text="Key 2" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button3" Text="Key 3" OnClick="ButtonClick" />
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
private static String key = "s";
// Handle the Navigate event
public void OnNavigateHistory(object sender, HistoryEventArgs e) {
LabelHistoryData.Text = Server.HtmlEncode(e.State[key]);
}
// On button click, handle the event and set a history point.
public void ButtonClick(object sender, EventArgs e) {
LabelHistoryData.Text = ((Button)sender).Text;
ScriptManager.GetCurrent(this).AddHistoryPoint(key, LabelHistoryData.Text, "Entry: " + LabelHistoryData.Text);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Microsoft ASP.NET 3.5 Extensions: Managing History</title>
<link href="../../include/qsstyle.css" type="text/css" rel="Stylesheet" />
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" OnNavigate="OnNavigateHistory"
EnableHistory="true" EnableSecureHistoryState="false" />
<h2>
Microsoft ASP.NET 3.5 Extensions: Adding Server-side Browser History Points and Title Entries</h2>
<p/>
<div id="Div1" class="new">
<p>This sample shows:</p>
<ol>
<li>How to use the <code>ScriptManager</code> control to set a history point and add titles.</li>
<li>The <code>ScriptManager</code> control, the <code>EnableHistory</code> and
<code>EnableSecureHistoryState</code> properties and
the <code>OnNavigate</code> property to handle the <code>navigate</code>event.<br />
</li>
</ol>
</div>
<p>
In this example, three buttons outside the <code>UpdatePanel</code> control can
trigger an asynchronous postback. You can see the results of the update through
the date and time that renders in the Web page along with a value indicating the
button that triggered the partial refresh.</p>
<p>
When you press a button, the server-side <code>Click</code> event handler for the button
stores data and uses the data as a history point. If you click the browser's Back button,
you will see the state Web page return to a previous button value, representing the previous
button you pressed. However, you will see that the time within the Web page continues to be
incremented.
</p>
<p>To see the effect of this logic, do the following.</p>
<ol>
<li>Press <b>1</b>. See the panel refresh.</li>
<li>Press <b>3</b>. See the panel refresh.</li>
<li>Press <b>2</b>. See the panel refresh.</li>
<li>Press the browser's Back button. Note that the panel is refreshed with previous
data, but the date and time are updated to current values.</li>
<li>Press the browser's "Recent Pages" drop down menu and review the history entries and their titles.</li>
</ol>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Button3" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Panel runat="server" CssClass="box" ID="Content" Height="40px">
Date and Time:
<%= DateTime.Now.ToLongTimeString() %>
<br />
Page's refresh state:
<asp:Label runat="server" ID="LabelHistoryData" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<p />
<asp:Button runat="server" ID="Button1" Text="Key 1" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button2" Text="Key 2" OnClick="ButtonClick" />
<asp:Button runat="server" ID="Button3" Text="Key 3" OnClick="ButtonClick" />
</div>
</form>
</body>
</html>