化惡魔為天使,巧移ViewState至SqlServer

iDotNetSpace發表於2009-07-23

ViewState一直以來備受爭議,主要是因為他臃腫的體積,導致客戶的的回傳(PostBack)資料量很大,而其中真正有用的資料又很少,網路頻寬被浪費不說,使用者的體驗也很差。

最近專案中用到了TelerikRadGrid,使用伺服器端繫結資料後頁面ViewState體積過大,而導致效能嚴重降低,便開始找尋優化方式,儘量將ViewState存在務器端

由於專案已開發至中期,不可能做類似於取消ViewState或使用客戶端繫結之類的大規模改動。

要想改動量最小化,肯定不能影響原有ViewState的使用,那隻能重寫Page類的LoadPageStateFromPersistenceMedium()SavePageStateToPersistenceMedium(object state)的方法,在這兩個Override的方法中把資料存在別的什麼地方。

這時候就來問題了,ViewState只是一個頁面的週期,每開啟一個頁面都會生成一個新的ViewState,連重新整理都不例外,如果存在檔案或資料庫中,這些資料累積起來可不是開玩笑的,而且也用不上了,那還不得要寫過期刪除的方法麼?太麻煩了。這時候,Session就發揮大作用了,Session的生命週期長於ViewState,過期會自動刪除,而且還是存在伺服器端的,不會增加資料傳輸量,看來很合適。

程式碼如下:

化惡魔為天使,巧移ViewState至SqlServer
public class AmoPage: System.Web.UI.Page
{
    
#region === Move View State To Session ===

    
private string _pageGuid = null;
    
public string PageGUID
    {
        
get
        {
            
if (_pageGuid == null)
                _pageGuid 
= this.Request.Form["__AmoViewState"];
            
if (_pageGuid == null)
                _pageGuid 
= Guid.NewGuid().ToString();
            
return _pageGuid;
        }
        
set { _pageGuid = value; }
    }

    
protected override object LoadPageStateFromPersistenceMedium()
    {
        
return Session[this.PageGUID];
    }

    
protected override void SavePageStateToPersistenceMedium(object state)
    {
        RegisterHiddenField(
"__AmoViewState"this.PageGUID);
        Session[
this.PageGUID] = state;
    }

    
#endregion
}


但是不能忽略一個問題,
Session預設是由WebServer 管理的,一般只用於儲存會話中使用者登入資訊這種資料量極小的情況,如果直接把ViewState這個大胖子塞進去,全部是儲存在記憶體中的,無疑用不了多長時間,WebServer就會因為Session資料量過大而崩潰。看來我們還需要轉移Session

正好,ASP.NET支援自定義會話管理的方式:

開始-> All Programs-> Microsoft Visual Studio 2008->Visual Studio Tools->Visual Studio 2008 Command Prompt

進入VS命令列模式。

執行 aspnet_regsql –S (192.168.19.250) –U sa –P 123 –ssadd

這是指使用使用者名稱sa 密碼123登入到SQLServer伺服器192.168.19.250上新增狀態管理相關的資料庫。其實它是建立了一個只有出口儲存過程的資料庫ASPState,並在系統資料庫tempdb中加入了兩張分別用於儲存Application Session的表。

這時候我們就完成了狀態管理相關的資料庫的建立,然後只要在 Web.config中做如下設定即可

<system.web>
    
<sessionState mode="SQLServer" sqlConnectionString="Data Source=192.168.19.250;User ID=sa;Password=123;">sessionState>
system.web>

這時候,該Web應用的Session資料就會儲存於資料庫中。

在使用的時候,只要將原有的頁面都從AmoPage類繼承就行。

至於效果,試過就知道!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-609988/,如需轉載,請註明出處,否則將追究法律責任。

相關文章