ASP.NET:压缩视图状态

发布于 2024-08-24 00:39:19 字数 996 浏览 6 评论 0原文

压缩 ASP.NET ViewState 内容的最新、最好的方法是什么?

这个的表现又如何呢?保持页面快速并最小化数据流量是否值得?

我怎样才能:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3NDEyOWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgkFLGN0b
DAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQxBSxjdGwwMCRDb250ZW50UGxhY2VIb
2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MQUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX01haW5Db250ZW50J
FJhZEJ1dDIFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQyBSxjdGwwMCRDb
250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MwUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX
01haW5Db250ZW50JFJhZEJ1dDQFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCd
XQ0BSxjdGwwMCRDb250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0NQUsY3RsMDAkQ29udGVud
FBsYWNlSG9sZGVyX01haW5Db250ZW50JFJhZEJ1dDXz21BS0eJ7991pzjjj4VXbs2fGBw==" />

变成这样的东西:

<input type="hidden" name="__VIEWSTATE"  id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3N==" />

What are the latest and greatest ways to compress the ASP.NET ViewState content?

What about the performance of this? Is it worth it to keep the pages quick and minimize data-traffic?

How can I make:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3NDEyOWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgkFLGN0b
DAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQxBSxjdGwwMCRDb250ZW50UGxhY2VIb
2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MQUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX01haW5Db250ZW50J
FJhZEJ1dDIFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQyBSxjdGwwMCRDb
250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MwUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX
01haW5Db250ZW50JFJhZEJ1dDQFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCd
XQ0BSxjdGwwMCRDb250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0NQUsY3RsMDAkQ29udGVud
FBsYWNlSG9sZGVyX01haW5Db250ZW50JFJhZEJ1dDXz21BS0eJ7991pzjjj4VXbs2fGBw==" />

Into sometning like this:

<input type="hidden" name="__VIEWSTATE"  id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3N==" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

污味仙女 2024-08-31 00:39:20

我意识到这是一个旧线程,但我们已经使用 Telerik 的 RadCompression HttpModule 一段时间了,它在压缩 ViewState、AJAX 和 Web 服务响应方面效果非常好。您还可以在会话中作弊并保存 ViewState - 适合低流量网站。

http://www.telerik.com/help/aspnet-ajax/radcompression.html

I realize this is an old thread, but we have been using Telerik's RadCompression HttpModule for a while now and it works incredibly well at compressing ViewState, AJAX and Web Service responses. You can also cheat and save ViewState in session - good for low traffic sites.

http://www.telerik.com/help/aspnet-ajax/radcompression.html

星軌x 2024-08-31 00:39:20

再次,经过一些研究后,我在一篇关于 压缩视图状态

为了保存压缩的视图状态,这就是我所做的:

protected override void SavePageStateToPersistenceMedium(object state) {
    SaveCompressedPageState(state);
}

private void SaveCompressedPageState(object state) {
    byte[] viewStateBytes;
    using(MemoryStream stream = new MemoryStream()) {
        ObjectStateFormatter formatter = new ObjectStateFormatter();
        formatter.Serialize(stream, state);
        viewStateBytes = stream.ToArray();
    }

    byte[] compressed = CompressionHelper.Compress(viewStateBytes);
    string compressedBase64 = Convert.ToBase64String(compressed);

    ClientScript.RegisterHiddenField(ViewStateFieldName, compressedBase64);
}

对于加载部分,这段代码使它对我有用:

protected override object LoadPageStateFromPersistenceMedium() {
    return LoadCompressedPageState();
}

private object LoadCompressedPageState() {
    string viewState = Request.Form[ViewStateFieldName];
    if(string.IsNullOrEmpty(viewState)) {
        return string.Empty;
    }

    byte[] decompressed = CompressionHelper.Decompress(viewState);
    string decompressedBase64 = Convert.ToBase64String(decompressed);

    ObjectStateFormatter formatter = new ObjectStateFormatter();
    return formatter.Deserialize(decompressedBase64);
}

Again, after some research into this I summarized my findings in a blog-post about Compressing View State.

To save a compressed View State, this is what I did:

protected override void SavePageStateToPersistenceMedium(object state) {
    SaveCompressedPageState(state);
}

private void SaveCompressedPageState(object state) {
    byte[] viewStateBytes;
    using(MemoryStream stream = new MemoryStream()) {
        ObjectStateFormatter formatter = new ObjectStateFormatter();
        formatter.Serialize(stream, state);
        viewStateBytes = stream.ToArray();
    }

    byte[] compressed = CompressionHelper.Compress(viewStateBytes);
    string compressedBase64 = Convert.ToBase64String(compressed);

    ClientScript.RegisterHiddenField(ViewStateFieldName, compressedBase64);
}

And for the loading-part, this code made it work for me:

protected override object LoadPageStateFromPersistenceMedium() {
    return LoadCompressedPageState();
}

private object LoadCompressedPageState() {
    string viewState = Request.Form[ViewStateFieldName];
    if(string.IsNullOrEmpty(viewState)) {
        return string.Empty;
    }

    byte[] decompressed = CompressionHelper.Decompress(viewState);
    string decompressedBase64 = Convert.ToBase64String(decompressed);

    ObjectStateFormatter formatter = new ObjectStateFormatter();
    return formatter.Deserialize(decompressedBase64);
}
各自安好 2024-08-31 00:39:20

Seb,ViewState 已经被压缩...这就是您所看到的...控件的压缩版本。如果你想要更少的开销,那么就不要使用 viewstate :)

Viewstate 的使用应该保持在最低限度!

Seb, ViewState is already compressed... that is what you are seeing... a compressed version of your controls. If you want less overhead, then don't use viewstate :)

Viewstate use should be kept to a minimum!

メ斷腸人バ 2024-08-31 00:39:20

这是您发布的视图状态的 XML 化可视化:

<viewstate>
  <Pair>
    <Pair>
      <String>1382774129</String>
    </Pair>
  </Pair>
</viewstate>
<controlstate>
  <HybridDictionary>
    <DictionaryEntry>
      <String>__ControlsRequirePostBackKey__</String>
      <ArrayList>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut3</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
      </ArrayList>
    </DictionaryEntry>
  </HybridDictionary>
</controlstate>

基本上只是一些想要了解其存在的单选按钮。 (如果未选中,浏览器不会将 字段与 postdata 一起发送)。这已经是很小的了。

它可以通过挂钩加载/保存方法或 HTTP 模块来压缩,但这可能并不实际,也不是真正需要的。


如果实际应用程序中的视图状态更大,请完全避免在视图状态中获取对象。这可以通过在 OnInit()Page_Init() 方法而不是默认的 Page_Load() 中初始化控件来实现。

其背后的原理可以在以下位置找到:
http://weblogs.asp.net/ infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
http://msdn.microsoft.com/en-us/library/ms972976 .aspx

快速总结:

  • ViewState 只是几乎所有控件属性(包括默认值)的后备存储。
  • 通过 OnInit() 设置默认值后,将调用 TrackViewState() 方法。
  • 任何后续更改(例如通过 Page_Load())或事件处理程序都将被跟踪并提交给客户端。这样,这些控件就可以在下一个请求时恢复其状态。
  • 不要依赖框架来恢复对象,而是在需要时在 OnInit() 中恢复对象。 (例如,从数据库重新填充DropDownList 的选项)。

一个例外是:

如果一个控件被动态添加到控件树中,它将起到追赶作用。它们的 OnInit() 方法可能会在稍后运行,导致这些属性最终出现在视图状态中。如果控件的初始化无法在 OnInit() 中进行,则可以使用设置 EnableViewState="false" 作为解决方法。

每次我的视图状态意外增长时,我都会使用“ViewState Decoder 2.2”应用程序来找出视图状态中最终出现的内容。通常,数据并不需要存在。

最后一句话:

视图状态不用于重新填充表单!!
这些值已与后期数据一起提交。

This is an XML-lized visualization of your posted viewstate:

<viewstate>
  <Pair>
    <Pair>
      <String>1382774129</String>
    </Pair>
  </Pair>
</viewstate>
<controlstate>
  <HybridDictionary>
    <DictionaryEntry>
      <String>__ControlsRequirePostBackKey__</String>
      <ArrayList>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut3</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
      </ArrayList>
    </DictionaryEntry>
  </HybridDictionary>
</controlstate>

Basically just a few radiobuttons which like to know of their existance. (browsers don't send an <input type="radio"> field with the postdata if it is not checked). This is pretty minimal already.

It can likely be compressed by hooking in the load/save methods or HTTP modules, but this may not be really practical nor really needed.


In case the viewstate is much bigger in your real app, avoid getting objects in the viewstate at all. This can be achieved by initializing the controls in the OnInit() or Page_Init() methods instead of the default Page_Load().

The rationale behind this can be found at
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
and http://msdn.microsoft.com/en-us/library/ms972976.aspx

A quick summary:

  • ViewState is just the backing store for almost all control properties, including defaults.
  • After the defaults are set by OnInit(), the TrackViewState() method will is called.
  • Any subsequent changes (e.g. by Page_Load()) or an eventhandler, will be tracked and submitted to the client. This way those controls can restore their state at the next request.
  • Instead of relying at the framework to restore objects, restore objects in OnInit() when needed. (e.g. repopulating the options of a DropDownList from the database).

One exception:

If a control is dynamically added to the control tree, it plays a catch-up. Their OnInit() method may run at a later moment, causing those properties to end up in the viewstate after all. If the initialization of the control can't happen in OnInit(), setting EnableViewState="false" can be used as workaround.

Each time my viewstate grows unexpectedly, I'm using the "ViewState Decoder 2.2" app to find out what ended up in the viewstate. Often, it's not needed for the data to be there.

And a final word:

The viewstate is not used for repopulating forms!!
Those values are already submitted with the postdata.

初见终念 2024-08-31 00:39:20

在某些情况下压缩视图状态会失败:
- 如果您在页面上使用更新面板,请不要使用压缩模式。
- 如果您以某种方式更改 ICallBack 代码结果的视图状态,请不要使用压缩模式,因为这不会反映回发时的正确视图状态。

Compressing view state fails in certain cases:
- If you are using update panel on page don’t use compression mode.
- If somehow you are changing the view state in result of ICallBack code don’t use compression mode, as this will don’t reflect the correct view state on post back.

意中人 2024-08-31 00:39:20

最小化视图状态的最佳方法就是不使用它。它会导致您进行一些额外的编程工作(在回发时重新填充控制值等,但它会节省您发送到浏览器的信息量)。你无法篡改它。

以下是 MSDN 上视图状态的链接:

http://msdn.microsoft .com/en-us/library/ms972976.aspx

以下是描述一些最佳实践的链接:

http://mnairooz.blogspot.com/2007/01/aspnet-20-viewstate-and-good-practices.html

一个关于禁用ViewState:

http://www.codeproject.com/KB/aspnet/ASPNET_Best_Practices.aspx

The best way to minimize the view state is just to not use it. It will cause you to do some extra work programming (repopulating control values etc on post back, but it will save you on the amount of information you send to the browser). You can't tamper with it.

Here is a link to the view state on MSDN:

http://msdn.microsoft.com/en-us/library/ms972976.aspx

Here is a link describing some best practices:

http://mnairooz.blogspot.com/2007/01/aspnet-20-viewstate-and-good-practices.html

And One on disabling the ViewState:

http://www.codeproject.com/KB/aspnet/ASPNET_Best_Practices.aspx

不可一世的女人 2024-08-31 00:39:19

简单的答案可能不是您想听到的。很多时候,页面上的控件默认具有视图状态,而实际上并不需要它。最好关闭视图状态,直到您知道需要它为止,并且仅在(希望如此)少数您确实想要保留视图状态的情况下才打开它。

The simple answer might not be what you want to hear. Too often, controls on the page have viewstate by default when they really don't need it. It's a good idea to switch off viewstate until you know you're going to need it, and only switch it on for the (hopefully) few cases where you actually want to keep the view state.

小矜持 2024-08-31 00:39:19
  1. 避免使用 ViewState
  2. 在 IIS 服务器上使用压缩。
  3. 您可以通过执行以下操作来连接将视图状态压缩到页面中或从页面中压缩出来的东西:
public abstract class PageBase : System.Web.UI.Page
{
    private ObjectStateFormatter _formatter = new ObjectStateFormatter();

    private static byte[] Compress( byte[] data )
    {
            var compressedData = new MemoryStream();
            var compressStream = new GZipStream(output, CompressionMode.Compress, true);
            compressStream.Write(data, 0, data.Length);
            compressStream.Close();
            return compressedData.ToArray();
    }
    private static byte[] Uncompress( byte[] data )
    {
            var compressedData = new MemoryStream();
            input.Write(compressedData, 0, compressedData.Length);
            input.Position = 0;
            var compressStream = new GZipStream(compressedData, CompressionMode.Decompress, true);
            var uncompressedData = new MemoryStream();
            var buffer = new byte[64];
            var read = compressStream.Read(buffer, 0, buffer.Length);

            while (read > 0)
            {
                uncompressedData.Write(buffer, 0, read);
                read = compressStream.Read(buffer, 0, buffer.Length);
            }
            compressStream.Close();
            return uncompressedData.ToArray();
    }
    protected override void SavePageStateToPersistenceMedium(object viewState)
    {
        var ms = new MemoryStream();
        _formatter.Serialize(ms, viewState);
        var viewStateBytes = ms.ToArray();
        ClientScript.RegisterHiddenField("__COMPRESSED_VIEWSTATE"
            , Convert.ToBase64String( Compress(viewStateArray)) );
    }
    protected override object LoadPageStateFromPersistenceMedium()
    {
        var compressedViewState = Request.Form["__COMPRESSED_VIEWSTATE"];
        var bytes = Uncompress( Convert.FromBase64String( compressedViewState ) );
        return _formatter.Deserialize( Convert.ToBase64String( bytes ) );
    }
}
  1. Avoid using ViewState
  2. Use compression on the IIS server.
  3. You can wireup something that will compress the viewstate into and out of a page by doing something like:
public abstract class PageBase : System.Web.UI.Page
{
    private ObjectStateFormatter _formatter = new ObjectStateFormatter();

    private static byte[] Compress( byte[] data )
    {
            var compressedData = new MemoryStream();
            var compressStream = new GZipStream(output, CompressionMode.Compress, true);
            compressStream.Write(data, 0, data.Length);
            compressStream.Close();
            return compressedData.ToArray();
    }
    private static byte[] Uncompress( byte[] data )
    {
            var compressedData = new MemoryStream();
            input.Write(compressedData, 0, compressedData.Length);
            input.Position = 0;
            var compressStream = new GZipStream(compressedData, CompressionMode.Decompress, true);
            var uncompressedData = new MemoryStream();
            var buffer = new byte[64];
            var read = compressStream.Read(buffer, 0, buffer.Length);

            while (read > 0)
            {
                uncompressedData.Write(buffer, 0, read);
                read = compressStream.Read(buffer, 0, buffer.Length);
            }
            compressStream.Close();
            return uncompressedData.ToArray();
    }
    protected override void SavePageStateToPersistenceMedium(object viewState)
    {
        var ms = new MemoryStream();
        _formatter.Serialize(ms, viewState);
        var viewStateBytes = ms.ToArray();
        ClientScript.RegisterHiddenField("__COMPRESSED_VIEWSTATE"
            , Convert.ToBase64String( Compress(viewStateArray)) );
    }
    protected override object LoadPageStateFromPersistenceMedium()
    {
        var compressedViewState = Request.Form["__COMPRESSED_VIEWSTATE"];
        var bytes = Uncompress( Convert.FromBase64String( compressedViewState ) );
        return _formatter.Deserialize( Convert.ToBase64String( bytes ) );
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文