2010-10-28 13 views
5

Quale evento del ciclo di vita della pagina ASP.NET posso scrivere il codice per determinare la dimensione del viewstate che viene inviato? Inoltre, è possibile determinare la dimensione senza analizzare l'HTML reso (come una proprietà sull'oggetto della pagina) o sta analizzando l'unico modo?Determinare la dimensione del viewstate della pagina ASP.NET prima di servire la pagina

Quello che mi piacerebbe fare è registrare le dimensioni, in particolare se superano una certa soglia.

+0

Ho finito per usare javascript e loggarlo in quel modo, ma @Aristos ha avuto la risposta al mio pensiero originale. – slolife

risposta

4

Si può andare sulla funzione che sta per scrivere il ViewState, il SavePageStateToPersistenceMedium. Questa è la funzione che anche utilizzato per comprimere viewstate ...

Ad esempio ...

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(); 

     .... 

    } 
} 

Alcuni riferimento.
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

Stai suggerendo di ignorare questo metodo in particolare? Quello funzionerebbe. Ma poi deve ereditarlo in ogni pagina, giusto? Come lo farebbe senza rielaborare ogni pagina? ~ Concesso, aggiungendo qualcosa ad ogni pagina come un evento OnSaveCompleted (o qualsiasi altra cosa) richiederà anche la rielaborazione di ogni pagina, quindi .../facepalm – jcolebrand

+1

@drachenstern Si crea la BasePage e quindi sul codebehind si dichiara come genitore non su System.Web.UI.Page, ma su BasePage. Sì, è necessario cambiarlo, su tutte le pagine (non così male) ... Penso che ci sia anche un modo automatico ma in questo momento non sono sicuro al 100% di rispondere se può andare bene ... – Aristos

+0

~ Sì, noi stai pensando la stessa cosa (faccio lo stesso con le mie pagine master ... ho un codice che è condiviso tra tutti loro) – jcolebrand

0

È possibile utilizzare SaveStateCompleted, che si verifica subito dopo che tutto lo stato è stato salvato nel viewstate. Per conoscere le dimensioni del viewstate, basta fare un conteggio dei caratteri dopo aver chiamato ToString sul viewstate.

ViewState.ToString.Count() 
+0

attraversandolo nel riflettore, che viene chiamato prima che la pagina venga visualizzata, no? E dal momento che non è stato ancora scritto, non puoi sapere con certezza quale sarà la dimensione o mancherò qualcosa? torna al riflettore! – jcolebrand

0

penso che, dopo aver guardato il meccanismo Reflector'd per la pagina e come gestisce ViewState, che si sta andando ad avere per andare a un HttpModule per ottenere ciò che sei dopo, se si desidera la dimensione effettiva dello stato di visualizzazione sulla pagina.

Dico questo perché dovrete ottenere la stringa letterale dalla pagina dopo che è stata sottoposta a rendering, il che non accade fino a dopo che tutti gli eventi definibili dall'utente sono stati attivati. Vedere uscita riflettore di seguito (parziale):

  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); 

In caso contrario, si può afferrare la viewstatebag e iterare il suo contenuto. Funziona bene anche a seconda di quanti dettagli vuoi entrare.

Problemi correlati