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
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.
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);
}
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
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:
OnInit()
, the TrackViewState()
method will is called.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.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.
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!
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