2010-10-28 49 views
5

我可以編寫哪些ASP.NET頁面生命週期事件來確定發送的視圖狀態的大小?另外,是否有可能在不通過呈現的HTML進行解析的情況下確定大小(如頁面對象上的屬性)還是解析唯一方法?在提供頁面之前確定ASP.NET頁面視圖狀態的大小

我想要做的就是記錄尺寸,特別是如果它們超過一定的閾值。

+0

我結束了使用JavaScript並記錄它,但@Aristos有我的原始思路的答案。 – slolife 2010-11-01 22:09:50

回答

4

你可以去對將要書寫的視圖狀態時,SavePageStateToPersistenceMedium功能。這是也是用來壓縮視圖狀態的功能...

例如...

public abstract class BasePage : System.Web.UI.Page 
{ 
    private ObjectStateFormatter _formatter = new ObjectStateFormatter(); 

    protected override void SavePageStateToPersistenceMedium(object viewState) 
    { 
     MemoryStream ms = new MemoryStream();  
     _formatter.Serialize(ms, viewState);  
     byte[] viewStateArray = ms.ToArray(); 

     .... 

    } 
} 

一些參考。
http://www.codeproject.com/KB/viewstate/ViewStateCompression.aspx
http://forums.asp.net/p/1139883/3836512.aspx
http://www.dotnetcurry.com/ShowArticle.aspx?ID=67&AspxAutoDetectCookieSupport=1

+0

你是否建議他特別重寫此方法?這將工作。但是,他必須在每一頁中繼承,對嗎?他如何做到這一點,而不用重新編輯每一頁? 〜授予,作爲OnSaveCompleted(或其他)事件將添加到每個頁面的東西需要重新處理每一頁,所以.../facepalm – jcolebrand 2010-10-28 20:45:48

+1

@drachenstern您創建BasePage,然後在代碼隱藏聲明爲父代不是System.Web.UI.Page,而是BasePage。是的,你需要改變這一點,在所有網頁上(沒有那麼糟糕)......我認爲也有一種自動方式,但在這一刻我不能100%肯定地回答,如果可以適應... – Aristos 2010-10-28 20:49:03

+0

〜是的,我們我正在考慮同樣的事情(我對我的MasterPages也是這樣做的......我有一些代碼在他們之間共享) – jcolebrand 2010-10-28 20:52:38

0

您可以使用SaveStateCompleted,它在所有狀態保存到視圖狀態後立即執行。要知道視圖狀態的大小,只需在視圖狀態調用ToString之後進行字符計數。

ViewState.ToString.Count() 
+0

在反射器中通過它,在頁面呈現之前被調用,否?而且由於它還沒有被寫入,所以你無法確定尺寸會是什麼,或者我錯過了什麼?回到反射器! – jcolebrand 2010-10-28 20:29:46

0

我想,看着Reflector'd機制頁面以及如何處理視圖狀態,那你將不得不去一個HttpModule讓你以後之後,如果你想在頁面上實際的viewstate大小。

我這樣說是因爲你將不得不在頁面被渲染後從頁面中獲取文字字符串,直到所有用戶可定義的事件觸發後纔會發生。請參閱下面的反射器輸出(部分):

  this.PerformPreRenderComplete(); 
      if (context.TraceIsEnabled) 
      { 
       this.Trace.Write("aspx.page", "End PreRenderComplete"); 
      } 
      if (context.TraceIsEnabled) 
      { 
       this.BuildPageProfileTree(this.EnableViewState); 
       this.Trace.Write("aspx.page", "Begin SaveState"); 
      } 
      if (EtwTrace.IsTraceEnabled(5, 4)) 
      { 
       EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_SAVE_VIEWSTATE_ENTER, this._context.WorkerRequest); 
      } 
      this.SaveAllState(); 
      if (EtwTrace.IsTraceEnabled(5, 4)) 
      { 
       EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_SAVE_VIEWSTATE_LEAVE, this._context.WorkerRequest); 
      } 
      if (context.TraceIsEnabled) 
      { 
       this.Trace.Write("aspx.page", "End SaveState"); 
       this.Trace.Write("aspx.page", "Begin SaveStateComplete"); 
      } 
      this.OnSaveStateComplete(EventArgs.Empty); 
      if (context.TraceIsEnabled) 
      { 
       this.Trace.Write("aspx.page", "End SaveStateComplete"); 
       this.Trace.Write("aspx.page", "Begin Render"); 
      } 
      if (EtwTrace.IsTraceEnabled(5, 4)) 
      { 
       EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_RENDER_ENTER, this._context.WorkerRequest); 
      } 
      if (str != null) 
      { 
       this.ExportWebPart(str); 
      } 
      else 
      { 
       this.RenderControl(this.CreateHtmlTextWriter(this.Response.Output)); 
      } 
      if (EtwTrace.IsTraceEnabled(5, 4)) 
      { 
       EtwTrace.Trace(EtwTraceType.ETW_TYPE_PAGE_RENDER_LEAVE, this._context.WorkerRequest); 
      } 
      if (context.TraceIsEnabled) 
      { 
       this.Trace.Write("aspx.page", "End Render"); 
      } 
      this.CheckRemainingAsyncTasks(false); 

否則,您可以抓住viewstatebag並遍歷它的內容。這也很好,取決於你想要進入多少細節。