使用Cross-Page Postback(跨頁面提交)在頁面間傳遞數據
2007-01-31 22:36 by Anders Cui, 1332 visits, 收藏, 編輯
頁面間傳遞數據的幾種方法
在頁面間傳遞數據時,我們有以下幾種選擇:
1、Query String
一個很常見的方法,Query String是URL中問號之後的那一部分。其優點在於它是輕量級的,不會給服務器帶來任何負擔。而它也有幾個缺點:傳遞的信息僅限於簡單的字符串,而且必須是合法的URL字符;信息是對用戶是可見的,因而存在安全性問題;用戶可能會嘗試手動修改查詢字符串,這可能是程序未預料到或不能防範的;很多瀏覽器對URL的長度都有所限制(通常爲1KB到2KB)。
2、Cookie
Cookie是創建在客戶端硬盤上(或者,如果它們是臨時的,則在內存中)的小文件。其優點在於使用時不易被用戶察覺,可被程序中每個頁面使用,並且可將數據長期保存。但它也有一些與Query String 相同的缺點:僅限於簡單的字符串信息;一旦用戶找到了相應的文件,它們也是易於訪問和閱讀的。所以Cookie最好不要用於保存複雜的或私密的信息。
3、Session
可以在源頁面中將數據保存在Session中,然後在目標頁面中讀取這些數據。注意:將大量的信息存儲在Session中會嚴重影響服務器的性能。
4、Server.Transfer
要進行服務器端的重定向,可以使用Server.Transfer。因爲在服務器端執行,Server.Transfer方法不需要請求另一頁面。使用HttpContext,我們可以在目標頁面中訪問源頁面中的數據。其缺點是,瀏覽器並不瞭解返回給它的是另外一個頁面,它在地址欄中會顯示第一個頁面的URL,這會讓用戶陷入混亂,在他們使用書籤的時候也會產生麻煩。所以不推薦該方法。
5、其它
還可以使用緩存(Cache)來存儲數據,可在程序的任意處訪問緩存。建議僅對那些修改不太頻繁但經常使用的數據使用緩存。 另外在某些特定情況下還可以使用Application變量,如統計頁面的點擊數等。
使用Cross-Page Postback
ASP.NET 2.0中引入了一個新的方法:跨頁面提交,即postback觸發在另一個頁面。這種技術聽起來很是簡單,但卻存在隱患。一不小心,就會導致你創建的頁面緊密耦合,難以維護和調試。
支持跨頁面提交的機制是一個名爲PostBackUrl的屬性,該屬性由IButtonControl接口定義,實現這個接口的按鈕控件包括ImageButton,LinkButton,Button。將PostBackUrl屬性值設置爲另一個web窗體的名稱(即URL),當用戶點擊按鈕時,頁面將被提交到新的URL。
看下面這個示例,該示例包括源頁面CrossPage1.aspx和目標頁面CrossPage2.aspx:
CrossPage1.aspx
<head runat="server">
<title>Source Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
FirstName: <asp:TextBox runat="server" ID="txtFirstName"></asp:TextBox>
<br />
LastName: <asp:TextBox runat="server" ID="txtLastName"></asp:TextBox>
<br />
<asp:Button runat="server" ID="cmdSubmit" PostBackUrl="~/CrossPage2.aspx" Text="Cross-Page Postback" />
</div>
</form>
</body>
</html>
CrossPage1.aspx不包含任何代碼,效果如下:
現在點擊按鈕,該頁面就被提交到CrossPage2.aspx了。此時CrossPage2.aspx頁面可以使用Page.PreviousPage屬性與CrossPage1.aspx進行交互了,下面這個事件處理函數演示瞭如何獲取源頁面的標題並顯示它:
{
lblInfo.Text = "You came from a page titled " + PreviousPage.Header.Title;
}
注意:該方法在訪問PreviousPage對象前先對其作了null檢查,如果結果爲false,表明沒有跨頁面提交發生,也就是說,CrossPage2.aspx是被直接請求的,或者由其自身提交,此時PreviousPage對象不可用。
從源頁面中獲取更多數據
上面那個示例作了一個有趣的嘗試,但僅僅如此,我們還是不能傳遞任何有用的信息。
要獲取源頁面中控件的值,可以使用FindControl方法:
{
lblInfo.Text = "You came from a page title " + PreviousPage.Header.Title;
string firstName = (PreviousPage.FindControl("txtFirstName") as TextBox).Text;
string lastName = (PreviousPage.FindControl("txtLastName") as TextBox).Text;
lblInfo.Text += "<br />";
lblInfo.Text += "your full name: " + firstName + " " + lastName;
}
要獲得更多信息,我們需要將PreviousPage引用轉換爲適當的頁面類(本示例中是CrossPage1類):
{
CrossPage1 prevPage = PreviousPage as CrossPage1;
if (prevPage != null)
{
// 此時可以訪問源頁面的公共屬性
}
}
另外,除了在代碼中進行類型轉換,還可以在.aspx頁面中添加PreviousPageType指示字:
<%@ PreviousPageType VirtualPath="~/CrossPage1.aspx" %>
此時,PreviousPage屬性會自動使用CrossPage1類型,編輯器中的智能提示也可以使用了。但是這種方法相當脆弱,因爲你只能使用一個頁面類!因此,出於靈活性考慮,使用類型轉換的方法會更好。
好了,不管怎樣,現在已經將PreviousPage對象轉換爲合適的頁面類型了,但是你還是不能直接訪問它包含的控件對象。這是因爲這些控件都被聲明爲保護類型(protected),此時的解決方案是使用屬性。
比如,如果希望公開源頁面上兩個文本框控件的值,可以添加屬性來封裝控件對象,如在CrossPage1類中添加屬性:
{
get { return txtFirstName; }
}
public TextBox LastNameTextBox
{
get { return txtLastName; }
}
但是,這通常不是最好的方法。其問題在於它公開了太多的細節,目標頁面可以讀取文本框控件的所有內容了。如果過段時間需要修改源頁面,決定使用不同的輸入控件,維護這些屬性就相當困難了,因爲你不得不修改兩個頁面的代碼。
更好的方法是定義更具體的屬性,它們應當僅僅提供你需要的東西。比如,你可以考慮添加一個FullName屬性,該屬性讀取兩個文本框的值:
{
get { return this.txtFirstName.Text + " " + this.txtLastName.Text; }
}
這樣做,兩個頁面的關係就變得清晰、簡單並易於維護了。如果你決定在CrossPage1中使用新的輸入控件,只要修改CrossPage1頁面就好了。CrossPage2中的代碼也相應地修改如下:
{
lblInfo.Text = "You came from a page titled " + PreviousPage.Header.Title + "<br />";
CrossPage1 prevPage = PreviousPage as CrossPage1;
if (prevPage != null)
{
lblInfo.Text += "You typed in this: " + prevPage.FullName;
}
}
下面是CrossPage2的最終結果:
跨頁面提交確實非常有用,但它們也會使頁面變得複雜。如果你允許多個源頁面提交到同一目標頁面,你就得編寫代碼邏輯以判斷頁面來自何處,然後作出相應處理。要避免這種煩惱,簡單的方法就是隻在兩個特定的頁面間使用它。
By Anders Cui
參考:
Beginning.ASP.NET.2.0.in.C.Sharp.2005.From.Novice.to.Professional by Matthew MacDonald
出處:http://anderslly.cnblogs.com
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。