本題考查面試者對ASP.NET中多頁面傳值的理解是否全面。因為ASP.NET的頁面表單提交到自身,完成回傳的功能,所以默認情況下不能使用POST方式進行多頁面傳值。關於這些傳值方式的分析如下所示。
1.URL傳值這是經典的傳值方式,這種方法的使用非常簡單,不過所傳遞的值是會顯示在浏覽器的地址欄上的,而且不能傳遞對象。所以這種方法一般用於傳遞的值少且安全性要求不高的情況下。在*.aspx頁面開發中可以使用超級鏈接文本進行傳值,如以下代碼所示。
<asp:HyperLink runat="server" ID="HpLink"
NavigateUrl="~/GetValues.aspx?urlvalue1=intel&urlvalue2=amd">URL傳值</asp:HyperLink>
以上鏈接文本將頁面跳轉到GetValues.aspx頁面,並且通過URL傳遞urlvalue1變量和urlvalue2變量,其值分別為intel和amd。在*.cs的服務器端方法中也可以調用HttpResponse對象的Redirect方法,將浏覽器端重定向到新頁面並通過URL傳值,如以下代碼所示。
Response.Redirect(“~/GetValues.aspx?urlvalue1=intel&urlvalue2=amd”);
2.Session傳值這種方法將每份數據存儲於服務器變量中,可以傳遞比較多的數據,並且安全性較高,所以常用於用戶身份的驗證功能中。不過,Session變量如果存儲過多的數據會消耗過多的服務器資源,編程者在使用時應該慎重,其使用方法如以下代碼所示。
Session["SessionValue"] = “ATI”;
//也可以用索引存儲
Session[0] = “ATI”;
//在其他頁面的服務器端方法中取值方式為:
string str = Session["SessionValue"].ToString();
//也可以用索引獲取
string str = Session[0].ToString();
Session的可在應用程序的多個頁面中以名稱/值對的方式共享,直到浏覽用戶關閉自己的浏覽器或者服務器Session超時(可設置,默認為20分鐘)。
3.Cookie傳值Cookie是一種比較特殊的數據存儲方式,因為這種方式將數據存儲於浏覽用戶的電腦中,以文本文件的形式存在於磁盤中。這種方式非常有意思,很多登錄系統就是利用Cookie實現用戶自動登錄。即用戶登錄一次的登錄信息將被寫入到用戶電腦的Cookie文件中,下次登錄時,網站自動讀取該Cookie完成身份驗證。通過Cookie傳遞數據雖然很方便,保存時間可以自由設置,但是安全性不高,編程者不應過於依賴Cookie,而應采用結合的方式完成敏感數據的存儲。
ASP.NET中操作Cookie的主要類型位於System.Web命名空間下,分別為HttpCookie、HttpResponse以及HttpRequest。HttpCookie可建立和操作獨立Cookie的安全類型,訪問HttpResponse和HttpRequest的Cookies屬性可以獲取HttpCookieCollection集合對象,以讀取或添加HttpCookie對象。添加Cookie的方法如以下代碼所示。
//創建一個HttpCookie 對象,向構造函數傳遞名稱值
HttpCookie ck = new HttpCookie("CookieValue");
//設置ck的“Value”屬性(值)
ck.Value = “Cookie值”;
//設置ck的過期時間為當前時間加上360s,即6分鐘後失效
ck.Expires = DateTime.Now.AddSeconds(360);
//設置ck有效范圍(域限制)
ck.Domain = "www.google.cn";
//將ck添加至HttpCookieCollection對象
Response.Cookies.Add(ck);
//也可為以下方法添加
//Response.AppendCookie(ck);;
讀取用戶的Cookie則更為簡單,只需根據名稱讀取HttpCookieCollection集合對象中的子項即可,如以下代碼所示。
string str = Request.Cookies["CookieValue"].Value;
除此之外,還可以利用一個HttpCookie存儲多個名稱/值對形式的Cookie信息,如以下代碼所示。
HttpCookie ck = new HttpCookie("CookieValue");
//以名稱/值對的方式添加多個Cookie信息
ck.Values.Add("value1", “on
e”);
ck.Values.Add("value2", "two");
//設置ck的過期時間為當前時間加上100年,即100年後失效
ck.Expires = DateTime.Now.AddYears(100);
//通過以下兩種方法添加
Response.Cookies.Add(ck);
//Response.AppendCookie(ck);
讀取這些Cookie如以下代碼所示。
string str = "值1:"+Request.Cookies["CookieValue"].Values["value1"];
str += "值2:" + Request.Cookies["CookieValue"].Values["value2"];
說明:多數浏覽器支持最多可達4096字節的Cookie,如果要將為數不多的幾個值保存到用戶計算機上,浏覽器還限制了每個站點可以在用戶計算機上保存的Cookie數量。大多數浏覽器只允許每個站點保存20個Cookie。如果試圖保存更多的Cookie,則最先保存的Cookie就會被刪除。還有些浏覽器會對來自所有站點的Cookie總數作出限制,這個限制通常為300個。用戶可以設置自己的浏覽器,拒絕接受Cookie,這種情況下只能結合其他的數據存儲方式。
4.Server.Transfer傳值這個方法的步驟相對較多,使用該方法編程者可以在另一個頁面以公開對象屬性的方式來存取值,使用這種方法是面向對象的。該方法的代碼編寫並不復雜,首先通過定義一個public權限的屬性,該屬性可返回所需傳遞的值。然後在第兩個頁面中,使用Context.Handler屬性來獲得前一個頁面實例對象的引用,即可通過訪問自定義的屬性獲取需要的值。
假設SendValues.aspx頁面為傳遞數據的頁面,在SendValues.aspx.cs的頁面類中定義一個public屬性,通過get直接返回需要傳遞的值(可為頁面中某個服務器控件的屬性值)。
public string TransferData
{
get
{
return "VIA";
}
}
在SendValues.aspx.cs的某個方法(如Button控件的Click事件處理方法)中調用HttpServerUtility對象的Transfer方法,如以下代碼所示。
Server.Transfer("~/GetValues.aspx");
假設GetValues.aspx為第二個頁面,在GetValues.aspx.cs的Page_Load方法中接收前一個頁面所傳遞的值,方法如以下代碼所示。
//定義SendValues類型的變量SV_Page
SendValues SV_Page;
//訪問HttpContext對象的Handler屬性,將值轉換為SendValues類型,引用賦值給SV_Page
SV_Page = (SendValues)Context.Handler;
//SV_Page即為SendValues.aspx頁面類的對象,直接獲取其TransferData屬性值
string str = SV_Page.TransferData;
可見,這種方法對於有面向對象基礎的編程者而言非常容易理解。不過頁面間如果需要傳遞數量比較多的值,這種方法需要定義過多的屬性,略顯繁雜。編程者還可以直接使用HttpContext對象的“Iterms”屬性添加多項名稱/值對的數據,在SendValues.aspx.cs調用HttpServerUtility對象的Transfer方法的某個方法中,修改代碼如下所示。
Context.Items["value1"] = "on
e";
Context.Items["value2"] = "two";
在GetValues.aspx.cs的Page_Load方法中接收前1個頁面所傳遞的值,修改代碼如以下代碼所示。
string str = "值1:" + Context.Items["value1"].ToString();
str += "值2:" + Context.Items["value2"].ToString();
5.Application傳值嚴格地說應該是通過HttpApplication對象在服務器端生成一個狀態變量來存儲所需的信息,該HttpApplication對象變量的可用范圍覆蓋整個WEB應用程序。所以該對象一般存儲一些要公布的信息,如在線人數等,而對於那些涉及用戶個人的敏感數據則不用這種方法存儲。HttpApplication對象有兩個常用的方法,即Lock和UnLock方法,可用於處理多個用戶對存儲在Application變量中的數據進行寫入的問題。Lock方法鎖定全部的Application變量,從而阻止其他用戶修改Application對象的變量值,UnLock方法則解除對HttpApplication對象變量的鎖定。通過HttpApplication對象傳值的方法和Session比較相似,在頁面類的某個方法中編寫代碼如下所示。
Application["a"] = "微軟公司";
Application["b"] = "蘋果公司";
Application["c"] = “Mac”;
以上代碼很輕松地將三個字符串值保存在HttpApplication對象的變量中了,並且這些變量是整個程序共享的,其他用戶通過相應的頁面同樣可以獲取。獲取這些變量的方法如以下代碼所示。
Application.Lock();
string str = "值1:" + Application["a"];
str += "值2:" + Application["b"];
str += "值3:" + Application["c"];
Application.UnLock();
注意:雖然使用方式和Session相似,但是Session是對於每個單獨的用戶,當該用戶關閉浏覽器,則Session失效。HttpApplication對象存儲的變量是針對所有訪問程序的用戶,即使有用戶關閉了浏覽器,變量的值不會丟失。
6.跨頁面傳送跨頁面傳送和調用HttpServerUtility對象的Transfer方法有相似之處,不過效率更高。因為調用HttpServerUtility對象的Transfer方法是基於服務器的方法,而跨頁面傳送是基於浏覽器端的。這個方法主要是設置控件的“PostBackUrl”屬性,使該控件(如Button)操作後轉向指定頁面,並且這個指定頁面可以直接獲取前一個頁面的所有控件對象及其屬性值。假設第一個頁面為SendValues.aspx,在該頁面中(非*.cs代碼文件)添加兩個控件,設置如以下代碼所示。
<asp:TextBox runat="server" ID="PbValue" Text="Geforce TX280"></asp:TextBox>
<asp:Button runat="server" ID="btn6" Text="跨頁面傳送方式" PostBackUrl="~/GetValues.aspx" />
以上代碼中,TextBox控件的“Text”屬性為“Geforce TX280”,這是所需要傳送的值。而Button控件的“PostBackUrl”屬性指定了GetValues.aspx頁面,該頁面即可接收所需傳遞的值。在GetValues.aspx.cs的Page_Load方法中,編寫以下代碼。
//PreviousPage為向當前頁面傳輸控件的頁面
if (PreviousPage != null)
{
//從PreviousPage容器中搜索“ID”為PbValue的控件,並轉換為TextBox類型
TextBox tb = (TextBox)PreviousPage.FindControl("PbValue");
//如果tb不是空引用
if (tb != null)
{
//將tb的“Text”屬性值給str變量
string str = tb.Text;
}
}
以上代碼輕松獲得了前一個頁面中TextBox控件的“Text”屬性值,這種方法比調用HttpServerUtility對象的Transfer方法更加快捷,並減少了處理步驟。
以上為常用的頁面間傳值方法,如果有特殊需要,還可以使用其他方法,例如通過數據庫存儲臨時數據等。