ASP.NET:压缩ViewState

Seb*_*son 10 compression asp.net viewstate webforms

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

这个表现怎么样?保持页面快速并最小化数据流量是否值得?

我怎么做:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3NDEyOWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgkFLGN0b
DAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQxBSxjdGwwMCRDb250ZW50UGxhY2VIb
2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MQUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX01haW5Db250ZW50J
FJhZEJ1dDIFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQyBSxjdGwwMCRDb
250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MwUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX
01haW5Db250ZW50JFJhZEJ1dDQFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCd
XQ0BSxjdGwwMCRDb250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0NQUsY3RsMDAkQ29udGVud
FBsYWNlSG9sZGVyX01haW5Db250ZW50JFJhZEJ1dDXz21BS0eJ7991pzjjj4VXbs2fGBw==" />
Run Code Online (Sandbox Code Playgroud)

进入这样的事情:

<input type="hidden" name="__VIEWSTATE"  id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3N==" />
Run Code Online (Sandbox Code Playgroud)

Ber*_*ann 8

简单的答案可能不是你想听到的.通常,当页面上的控件确实不需要时,它们默认具有viewstate.关闭viewstate是个好主意,直​​到你知道你将需要它为止,并且只在(实际上)你想要保持视图状态的少数情况下打开它.

  • +1我认为我们都不会因为没有检查我们的网页而感到内疚. (3认同)

Tho*_*mas 8

  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 ) );
    }
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*uer 6

我意识到这是一个旧线程,但我们已经使用Telerik的RadCompression HttpModule一段时间了,它在压缩ViewState,AJAX和Web Service响应方面非常出色.您还可以在会话中作弊并保存ViewState - 适用于低流量站点.

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


Seb*_*son 2

同样,经过一些研究后,我在一篇关于压缩视图状态的博客文章中总结了我的发现。

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,通过创建 ObjectStateFormatter 实例,它不会获得对其所使用的页面的引用,因此不会尝试加密视图状态。通过这种方式,您的序列化视图状态更容易压缩,尽管无论您的配置如何,它都不会被加密。 (2认同)