【问题标题】:Determine size of ASP.NET page's viewstate before serving page在提供页面之前确定 ASP.NET 页面的视图状态的大小
【发布时间】:2011-05-02 02:25:13
【问题描述】:

我可以在哪些 ASP.NET 页面生命周期事件中编写代码来确定发出的视图状态的大小?此外,是否可以在不解析呈现的 HTML(如页面对象上的属性)的情况下确定大小,还是解析唯一的方法?

我想做的是记录大小,特别是当它们超过某个阈值时。

【问题讨论】:

  • 我最终使用了 javascript 并以这种方式记录它,但 @Aristos 回答了我最初的思路。

标签: asp.net viewstate


【解决方案1】:

你可以继续编写视图状态的函数,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

【讨论】:

  • 您是否建议他特别重写此方法?那会奏效。但是他必须在每一页中继承它,对吗?如果不重新修改每一页,他将如何做到这一点? 〜当然,将某些内容作为 OnSaveCompleted(或其他)事件添加到每个页面也将需要重新处理每个页面,所以 ... /facepalm
  • @drachenstern 您创建了 BasePage,然后在代码隐藏中声明为父级的不是 System.Web.UI.Page,而是 BasePage。是的,您需要在所有页面上进行更改(还不错)...我认为还有一种自动方式,但目前我不能 100% 确定回答是否适合...
  • ~ 是的,我们在想同样的事情(我的 MasterPages 也是这样......我有一些代码在他们之间共享)
【解决方案2】:

您可以使用 SaveStateCompleted,它在所有状态都保存到视图状态之后立即发生。要知道视图状态的大小,只需在视图状态上调用 ToString 后进行字符计数。

ViewState.ToString.Count() 

【讨论】:

  • 在反射器中逐步通过它,在页面渲染之前调用它,不是吗?而且由于它还没有写出来,你不能确定它的大小,还是我错过了什么?回到反射器!
【解决方案3】:

我认为,在查看了 Page 的 Reflector 机制以及它如何处理视图状态之后,如果你想要实际的视图状态大小,你将不得不去一个 HttpModule 来获得你想要的东西页面。

我这样说是因为您必须在页面呈现后从页面中获取文字字符串,直到所有用户可定义的事件都触发后才会发生。请参阅下面的反射器输出(部分):

            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 并迭代其内容。这也很有效,具体取决于您想要了解多少细节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 1970-01-01
    • 2019-10-25
    • 2020-01-26
    相关资源
    最近更新 更多