預設情況下,在 ASP.NET 網頁中引起回傳的按鈕和其他控制項將頁提交回該頁本身。這是 ASP.NET 網頁在其正常的處理過程中所要經曆的往返周期的一部分。在某些情況下,可能需要將一個頁發送到其他頁。例如,您可能正在建立一個收集每個頁上不同資訊的多頁表單。在此情況下,可以將頁中的某些控制項(實現 IButtonControl 介面的控制項,如 Button 控制項)配置為發送至不同的目標頁。這被稱為跨頁發送。跨頁發送與使用 Transfer 方法重新導向到其他頁相比,具有一些優點。
從源頁擷取資訊
為跨頁發送配置頁時,您通常需要從源頁中擷取資訊。這可能包括來自頁上控制項的資訊(即由瀏覽器發送的資訊),以及源頁的公用屬性。
擷取控制項值
Page類公開一個名為PreviousPage的屬性。如果源頁和目標頁位於同一 ASP.NET 應用程式中,則目標頁中的PreviousPage屬性包含對源頁的引用。(如果該頁不是跨頁發送的目標或者這些頁位於不同的應用程式中,則不會初始化PreviousPage屬性。) 預設情況下,PreviousPage屬性類型化為Page。
如果源頁和目標頁位於不同的應用程式中,則無法直接擷取頁上控制項的值,但可以從 Form 字典中讀取發送的資料。因為源頁經過散列處理,所以不能從源頁中閱讀檢視狀態。如果要在源頁中儲存值並使這些值可供其他應用程式中的目標頁使用,則可以將這些值作為字串儲存在源頁的隱藏欄位中,並在目標頁中通過 Request.Form 來訪問它們。
在 PreviousPage 屬性中使用引用,便可以搜尋源頁上的控制項並提取這些控制項的值。通常使用 FindControl 方法來執行此操作。
if (Page.PreviousPage != null){ TextBox SourceTextBox = (TextBox)Page.PreviousPage.FindControl("TextBox1"); if (SourceTextBox != null) { Label1.Text = SourceTextBox.Text; }}
FindControl 方法在當前的命名容器中尋找控制項。如果要尋找的控制項位於另一控制項內(通常位於模板內),則必須先擷取對該容器的引用,然後才能在該容器中尋找要擷取的控制項。在下面的程式碼範例中,源頁包含一個 Login 控制項,並具有一個 LayoutTemplate 容器,而該容器又包含一個名為 UserName 的 TextBox 控制項。該代碼擷取 UserName 控制項的值。
Login LoginControl = (Login)PreviousPage.FindControl("Login1");if (LoginControl != null){ TextBox UserName = (TextBox)LoginControl.FindControl("UserName"); if (UserName != null) { Label1.Text = UserName.Text; }}else{ Label1.Text = "Cannot find user name in Login control.";}從源頁擷取公用屬性值
在跨頁發送的目標頁中,也可以擷取源頁的公用成員的值。最常見的方案是源頁定義公用屬性,並且您要在目標頁上擷取這些屬性的值。
建議您只將需要的資訊作為公用屬性公開,以減少可能被潛在的惡意使用者使用的資訊量。
若要擷取源頁的公用成員,必須先擷取對源頁的強型別引用。
可以通過多種方法來執行此操作。第一種方法是在目標頁中包含一個@ PreviousPageType指令,該指令允許您指定源頁,如此樣本中所示:
<%@ PreviousPageType VirtualPath="~/SourcePage.aspx" %>
包含此指令時,PreviousPage 屬性被強型別化為被引用的源頁的類。因此,可以直接引用源頁的公用成員。可以使用 type 屬性直接指定源頁的類型,也可以通過在 VirtualPath 屬性中顯式引用源頁來間接指定源頁的類型,如該樣本中所示
下面的程式碼範例示範源頁的一部分,其中包含一個名為 CurrentCity 的公用屬性,該屬性用於公開名為 textCity的 TextBox 控制項的值。
public String CurrentCity{ get { return textCity.Text; }}
在源頁上建立的、主要用於為跨頁發送公開值的屬性通常是唯讀屬性。儘管源頁可以包含公用讀取/寫屬性,但是通過目標頁屬性設定源頁屬性一般沒有任何效果,因為不會保留此值。
如果目標頁中包含指向源頁的 PreviousPageType 指令,則可以使用下面的代碼訪問源頁的 CurrentCity 屬性。
Label1.Text = PreviousPage.CurrentCity;
擷取對源頁的強型別引用的另一種方法是在引用源頁的目標頁中包含一個@ Reference指令,正如引用要在頁中使用的任何類型一樣。在此情況下,您可以在目標頁中擷取目標頁的PreviousPage屬性並將其強制轉換為源頁類型,如下面的程式碼範例所示。
SourcePage_aspx sourcePage;sourcePage = (SourcePage_aspx) PreviousPage;Label1.Text = sourcePage.CurrentCity;
@ Reference的用法例子下載檢查目標頁中的回傳
在跨頁回傳過程中,源頁控制項的內容被發送至目標頁,並且瀏覽器執行 HTTP POST 操作(不是 GET 操作)。但在目標頁中,在跨頁發送之後,IsPostBack屬性便立即成為 false。儘管該行為是 POST 的行為,但跨頁發送並不是到目標頁的回傳。因此,IsPostBack 設定為 false,並且目標頁可以通過它的第一次代碼。
如果這在您的應用程式中有用,則可以確定目標頁是否由於跨頁發送而正在運行。為此,您可以對目標頁的PreviousPage屬性返回的頁引用的IsCrossPagePostBack屬性進行測試,如下面的程式碼範例所示。
if(PreviousPage != null){ if(PreviousPage.IsCrossPagePostBack == true) { Label1.Text = "Cross-page post."; }}else{ Label1.Text = "Not a cross-page post.";}
請注意,如果當前頁不是跨頁發送的目標,則 PreviousPage 屬性返回 null(在 Visual Basic 中為 Nothing)。
跨頁發送與 Server.Transfer
PreviousPage屬性和 PreviousPageType 指令在調用目標頁的兩種情況下都很有用:在跨頁回傳中(這是一種基於用戶端的傳輸)和使用Transfer 方法時(這是基於伺服器的操作)。在以上兩種操作中,目標頁中的代碼都可以使用PreviousPage 屬性擷取對源頁的引用。
在目標頁中,確定頁是通過跨頁發送還是 Server.Transfer 操作調用可能很重要。為了協助您執行此操作,Page 類公開了一個名為IsCrossPagePostBack 的屬性