【轉】http://www.cnblogs.com/infim/archive/2010/08/25/1808035.html
在Web 應用程序中,頁面之間交換數據(傳值)是一種基本應用,它的實現效率對程序性能有直接的影響。傳統的解決方案是通過Get 或Post 方法來實現的。但在ASP.NET 中,這2 種方法的使用發生了變化。因為ASP.NET使用了基於事件驅動的編程模型,頁面采用了PostBack 技術(發回給自己),一些傳統的方法必須做出一定的調整才能適應它。同時,ASP.NET 以其優秀的架構提供了更多可用於頁面間傳值的方法。這些方法各具特色,比較充分地適應了各種情況下頁面間傳值的需求。
1 頁面重定向
頁面間的傳值方法總是與一定的頁面重定向方法相聯系,而且有些傳值方法只能用某種重定向方法才能實現。ASP.NET 中有多種頁面重定向的方法,這里僅介紹下文中用到(也是最常用的)的2 種。
(1)Redirect 方法
將客戶端重定向到新的頁面,只是簡單地終止當前頁面,並轉入新的頁面開始執行,對轉入的頁面無任何限制。
(2)Transfer 方法
終止當前頁的執行,並為當前請求開始執行新的頁面。把執行流程從當前頁面轉到同一服務器中的另一頁面,但是新的頁面仍然使用當前頁面創建的應答流。
這兩種方法的主要區別是:
(1)Redirect 方法可以實現任意網頁間的重定向,而Transfer 方法只能實現同一服務器中ASPX 頁面間的重定向。
(2)Redirect 方法不會保留當前頁面的表單(Form)數據和查詢字符串(QueryString),而Transfer 方法則可以保留這些數據。
2 傳值方法
為 了簡化問題的討論,本文作如下約定:示例基於C#語言;源頁和目標頁已經導入了必要的命名空間;源頁面設為Src.aspx,值的傳送點設在控件 Button1 的Click 事件中,待傳送的數據保存在控件TextBox1中; 目標頁面設為Dst.aspx,值的接收點設在該頁面的Page_Load 事件中,接收的數據顯示在控件Label1 中;不深入討論與之相關的編程問題,所有示例僅給出基本實現方法,所有代碼在Visual Studio2005 中調試通過。
2.1 QueryString 的使用
最簡單最常用的傳值方法,與傳統的 Get 方法相對應,使用變化相對較小。數據直接在URL 中以明文傳遞,對於用戶來說是可見的,但是可以加密。此方法的優點是簡單、方便,缺點是能傳遞的數據量少,而且不能傳遞對象。
示例如下:
Src.aspx:
Private void Button1_Click(object sender, EventArgs e)
{
//將待傳送的數據保存到URL 中
strUrl=“Dst.aspx?id=”+TextBox1.Text;
//重定向到目標頁面
Response.Redirect(strUrl);
}
Dst.aspx:
private void Page_Load(object sender, EventArgs e)
{
//接收數據並顯示在Label1 控件中
Label1.Text = Request.QueryString[“id”];
}
2.2Form 的使用
通過表單中的控件來傳遞數據,與傳統的Post方法相對應,使用變化相對較大。該方法的優點是可以傳遞大量數據,並且可以訪問源頁面控件中的數據;缺點是操作比較復雜,生命周期僅限於當前請求。
示例如下:
Src.aspx:
public string id{get{return TextBox1.Text;}} //定義公共屬性
Server.Transfer("Dst.aspx"); //重定向到目標頁面
Dst.aspx:
//HTML 中引入PreviousPageType 指令
<%@ PreviousPageType VirtualPath="~/Src.aspx" %>
//代碼中獲取Form 數據
Label1.Text=PreviousPage.id;
該方法的實現靈活多樣。文獻[1]中給出了使用Transfer進行傳值的方法,其他一些文獻中給出了使用隱藏域或者隱藏字段進行傳值的方法,筆者認為其實都是使用Form 進行傳值。因為傳值過程中使用的數據載體是Form,而不是其他東西。
2.3 Session 的使用
Sessionss 對象為當前用戶會話提供信息。通過其屬性可以方便地設置和檢索ASP.NET 會話狀態變量,這些變量的值在會話持續期間保留不變,並且可以被同一個會話中的所有頁面訪問,這就為頁面傳值提供了途徑和方便。該方法的特點是:
(1)用戶數據存儲在服務器端;
(2)ASP.NET 中的Session 對象也可以不依賴Cookie 而正常工作;
(3)可以直接存儲對象,且無大小限制;
(4)有效期與用戶的活動時間有關,具體為用戶活動時間+自定義延遲時間。
該方法的缺點是:由於Web 應用程序對每個用戶都會生成Session 變量,因此它會隨着用戶數量的增多而加重服務器的負擔。如果數據量比較小,Sessionss 對象是保存只需要在當前對話中保持的特定數據的極好位置。
實例代碼如下:
Src.aspx:
Session[“id”]=TextBox1.Text;
Response.Redirect(“Dst.aspx”);
Dst.aspx:
Label1.Text=Session[“userid”].ToString();
Session.Remove(“id”); //清除Session 變量
2.4 Application 的使用
Application 對象提供了對應用程序狀態的訪問。與Session 對象相比,兩者對數據的存儲與訪問都相似,不同之處在於:每個Web 應用程序只生成一個Application 實例,並應用於所有的用戶和會話;有效期為整個Web 應用程序的生命周期。因此,該方法非常適合存儲那些數量少、不隨用戶變化而變化的常用數據。在多用戶並發訪問控制方面,Apllication 對象采用了鎖定機制,但是它串行化了對Application 對象的訪問,而這對於應用程序來說有可能形成嚴重的性能瓶頸。
示例如下:
Src.aspx:
Application[“id”]=TextBox1.Text;
Response.Redirect(“Dst.aspx”);
Dst.aspx:
Application.Lock(); //加鎖
Label1.Text=Application[“userid”].ToString();
Application.Unlock(); //解鎖
Application.Remove(“id”); //清除Application 變量
2.5 Cookie 的使用
Cookie 是網站存放在用戶機器上的一小塊信息,主要用來保存一些與用戶相關的東西。瀏覽器一般都對Cookie 的使用進行了一些限制:
(1)每個域最多只能在一台用戶機器上存儲20 個Cookie;
(2)每個Cookie 的總尺寸不能超過4 096 Byte;
(3)一台用戶的機器上Cookie 的總數不能超過300 個。
該方法的缺點是:並非所有的瀏覽器都支持Cookie;用戶可以禁用和刪除它;信息采用明文保存,安全性差。當特定的用戶需要特定的數據片,並且需要把數據在某個可變的時段中保持的時候,Cookie 就非常方便。
實例代碼如下:
Src.aspx:
Response.Cookies[“id”].Value=TextBox1.Text;
Response.Redirect(“Dst.aspx”);
Dst.aspx:
Label1.Text=Request.Cookies[“id”].Value;
//清除Cookie 變量
Response.Cookies[“id”].Expires=Now.AddDays(-1);
//清除當前域名(和路徑)下的所有Cookie
Response.Cookies[cookie].Expires=Now.AddDays(-1);
2.6 Static(靜態)變量的使用
准 確地說,是使用類的公共靜態變量。這種變量在應用程序運行期間分配固定的存儲空間,它依類而不依類實例而存在,使用時直接通過類名即可訪問。在 ASP.NET 中,每個頁面對應一個類,因此,可以利用它們的公共靜態變量在頁面間傳遞數據。該方法的優點是如果善加利用,則可以有效提高數據傳遞效率,缺點是如果濫用,則會導致用戶或頁面間數據紊亂,造成極大的隱患。
示例如下:
public static string id; //在類Src 中定義公共靜態變量
Src.aspx:
id=TextBox1.Text;
Response.Redirect("Dst.aspx");
Dst.aspx:
Label1.Text=Src.id;
2.7 Cache 的使用
應 用程序中的緩存機制用於將需要大量服務器資源來創建的對象存儲在內存中,以此大大改進應用程序的性能。這個機制同樣可以用來傳值。與其他方法不同的是,該 方法需要設置緩存項優先級和緩存時間。因為當系統內存缺乏時,緩存機制會自動移除很少使用或優先級較低的項,從而造成傳值失敗。該方法的優點是傳遞數據的大小和數量無限制,速度快。缺點是緩存機制的操作相對比較復雜。在ASP.NET 中,緩存機制通過Cache 類實現。
示例如下:
Src.aspx:
Cache["id"]=TextBox1.Text;
Response.Redirect("Dst.aspx");
Dst.aspx:
if(Cache["id"]!=null) Label1.Text=Cache["id"].ToString();
Cache.Remove("id"); //移除緩存項
如果 Cache["id"]為空,則傳值失敗。可使用如下方法實現過期策略(以10 min 過期為例):
Cache.Insert("id",TextBox1.Text,null,
Cache.NoAbsoluteExpiration,new TimeSpan(0,10,0));
2.8 Context 的使用
Context 對象包含與當前頁面相關的信息,提供對整個上下文的訪問,包括請求、響應、以及上文中的Session和Application 等信息。可以使用此對象在網頁之間共享信息,從而實現頁面間的傳值。與使用 Form 的方法類似,該方法也能保持大量的數據,缺點也相同,但使用方法相對比較簡單。
示例如下:
Src.aspx:
Context.Items["id"]=TextBox1.Text;
Server.Transfer("Dst.aspx");
Dst.aspx:
Label1.Text=Context.Items["id"].ToString();
Context.Items.Remove("id"); //移除項
2.9 ViewState 的使用
ViewState 是ASP.NET 用來在同一頁面的多個請求之間保存和還原服務器控件視圖狀態的一種機制。與傳統的“同一頁面”不同ASP.NET 中“同一頁面”的每一個請求都會導致服務器重新生成該頁面,但是新生成的頁面並不包含原來頁面的數據。ViewState 的任務就是保存原來頁面中服務器控件視圖狀態的數據供新頁面使用。從這個意義上講,ViewState 也可以看作是一種在頁面間傳遞數據的工具。ViewState 的工作原理是:作為一個隱藏的窗體字段在客戶端和服務器之間傳遞,可見,濫用ViewState 會加重頁面回傳的負擔,從而降低應用程序的性能。此外,ViewState 也能被控件、頁面和應用程序禁用。
示例如下(在同一頁面中):
ViewState["id"]=TextBox1.Text; //數據保存
Label1.Text=ViewState["id"].ToString(); //數據取出
ViewState.Remove("id"); //數據移除
2.10 Web.config 和Machine.config 的使用
Web.config 文件用來設置每個ASP.NET 應用程序的一些屬性,Machine.config 文件用來設置所有應用程序基礎信息。這 2 種文件保存的數據一般都很小,多為明文,特別適合保存一些字符串常量,如數據庫連接信息。此外,Web.config 文件是可以擴展的,因此,也可以用來傳遞變量。因為這 2 種文件會被自動緩存,所以不存在因磁盤I/O產生的性能瓶頸問題。要注意的是文件中某些設置會導致文件被修改后Web 應用程序的重啟。
示例如下:
Src.aspx:
WebConfigurationManager.AppSettings.Set("id",
TextBox1.Text);
Dst.aspx:
Label1.Text=WebConfigurationManager.AppSettings["id"];
//數據移除
WebConfigurationManager.AppSettings.Remove("id");
2.11 其他方法
在 其他方法中應用最多最廣的就是數據庫了,比較常見的還有文件。相對於數據庫來講,文件需要自定義格式,還有可能因磁盤I/O 而產生性能瓶頸,設計和使用的工作量都比較大,除非必要,很少應用。數據庫和文件在程序中應用廣泛,幾乎可以存儲任何類型、任何尺寸和數量的任何信息,而且可以永久保存。考慮到數據庫和文件都是通用技術,此處不作詳述。對於其他傳值方法,或者應用極少,或者是上述方法的
變種,這里不作討論。
3 比較與分析
傳值方法 |
生命周期 |
應用范圍 |
數據類型 |
數據大小 |
使用QueryString |
與目標頁有關 |
單用戶 |
字符串 |
1KB |
使用Form |
當前請求 |
單用戶 |
全部 |
不限 |
使用Session |
當前會話 |
單用戶 |
全部 |
不限 |
使用Application |
應用程序 |
全局 |
全部 |
不限 |
使用Cookie |
可自定義 |
單用戶 |
字符串 |
4KB |
使用Static變量 |
應用程序 |
全局 |
全部 |
不限 |
使用Cache |
可自定義 |
全局 |
全部 |
不限 |
使用Context |
當前請求 |
單用戶 |
全部 |
不限 |
使用ViewState |
當前頁 |
單用戶 |
全部 |
不限 |
使用Web.config和Machine.config |
可永久 |
全局 |
字符串 |
不限 |
使用數據庫或文件 |
永久 |
全局 |
全部 |
不限 |
表中的“當前請求”指目標頁的第1 次加載到目標頁回發操作或作廢前;“當前會話”指用戶活動時間+自定義延遲時間;“應用程序”指應用程序的生命周期。數據大小的“不限”並非指無限,因為 要受存儲介質的限制。在程序中動態寫入Web.config 中的數據默認不保存到該文件中,應用程序重啟后會消失。通過前文的論述和上表的比較可以看出:傳遞無需保密的簡單數據使用QueryString 最方便;通過控件直接傳遞數據只能使用Form;傳遞只與具體用戶有關的數據使用Session最合適;要想在所有的用戶間共享數據使用 Application 比較方便,而共享數據如果是字符串常量則使用Web.config 也是很好的選擇;Static 變量可以長時間保持數據,而Cache 會自動清除數據,Context 還具有訪問請求、會話以及Application的能力;如果要長期保存數據,則只能在Cookie、Web.config、數據庫或文件之中選擇;除使用數據庫或文件之外,數據傳遞速度都很快,只要設計得當,一般不會形成性能瓶頸。總之,每種方法都有其自身的特點與優勢,實際應用中選取何種方法應該根據 具體情況具體分析,不能一概而論。
4 結束語
無論何種傳值方法,都有其適用的條件和范圍,都有其優缺 點。在實際應用中,應該根據需求,仔細、全面地權衡各種方法的利弊,比較它們的應用效果,才能做出較佳的選擇。一般來說,要考慮的主要因素有數據的保密性、類型、數據量的大小、使用范圍和保持時間長短等。既要滿足需求,又要盡可能簡單易行,還要兼顧應用程序的性能優化。在實踐中,還要不斷嘗試,不斷分析 和總結經驗,才能充分理解和靈活運用這些方法,從而更好地解決各種實際問題。