I'm currently fighting with the .NET Viewstate and it is starting to wear me down. Having found that some of the pages in one of our applications is made up of around 80% viewstate I have looked into reducing this where I can.
I have looked at (and am happy with) disabling viewstate for controls that do not need it (labels, buttons etc) and have made some small gains here.
I'm now looking at viewstate compression and while I can demonstrate a 40-50% decrease in size it does not seem to be playing well with my application.
Scenario: Page contains a few dropdown lists, a button and a Grdiview (hence the need to deal with the ViewState!). When the page loads the DDLs are populated and default selections are made. Pressing the OK button results in the Gridview being populated as expected.
Now the problem: With Viewstate Compression enabled, if the user changes the selected items in the DDLs before clicking the OK button they will get a 'Required Field Validator' error indicating that a selection has not been made in one of the DDLs - but this is not the case! Disabling the compression code removes the problem and the page operates as expected (i.e. as it has for months!).
Could the problem be down to the viewstate now being stored in a key other than __VIEWSTATE [the code that I have seen use different key names - VSTATE for instance).
My page sources look like this;
Page Source with Compression (note the empty __VIEWSTATE key):
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
<input type="hidden" name="__VSTATE" id="__VSTATE" value="H4sIAAAAAEAO29B2AcSZYlJ
.
.
MKd2afqdaImFR5UiFXVyQPwLPA//8xt+pMsSQ8vlOklcoNgmZfJd8hHvk6/S/7UbxxAJTjzZfp6Qcm039
h3d3dvvPO7/Oa/7i57uemj1H2a/gw5lJQ+ySjFRtPZUL7A/3o2ImFR5UiFXVyLPA+38At70F1EkwAAA=" />
<input type="hidden" name="__VIEWSTATE" id="
__VIEWSTATE" value="" />
</div>
Page Source without Compression:
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTYxOTM1NDg4N
A9kFgJmD2QWAgIDD2QWAgIFD2QWAmYPZBYKAgEPZBYIAgcPZBYCAgMPDxYCHgRUZXh0BRdEYXduQyBbY2hhbm
dlIHBhc3N3b3JkXWRkAgkPFgIeB1Zpc2libGVoFgQCAQ8PFgIfAAUFQWRtaW5kZAIDDw8WAh8ABQUxNDoyNGR
.
.
.
.
.
.
kAgsPDxYEHwAFWVNlbGVjdGVkIFNlcnZpY2UgVXNlcjogPGEgY2xhc3M9J3N1U2VsZWN0b3InIGhyZWY9J2xp
c3RzZXJ2aWNldXNlcnMuYXNweCc+PGI+bm9uZTwvYj48L2E+HwFoZGQCDw8QZGQWAGQCBQ8UKwADZDwrABQEA
BYSHg9QYXJlbnRJdGVtQ2xhc3MFC2lnbW5fUGFyZW50HhdUb3BMZXZlbFBhcmVudEl0ZW1DbGFzcwUTaWdtbl
Ub3BFBhcmVudB4KSlNGaWxlTmFtZWUeFlRvcExldmVsSG92ZXJJdGVtQ2xhc3MFNGlnbW5fVG9wTGV"
/>
</div>
How does .NET know where the VIEWSTATE is stored and does it know that i have moved it?
Do I need to make any other changes to my code apart from implementing SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium?
Edit: I've got to the bottom of this - well almost, I have it working!
For some reason using the ClientScript.RegisterHiddenField method appears to have been the source of the problem. Modifying the code to utilise the base class save method, i.e. base.SavePageStateToPersistenceMedium(compressedBytes)
and processing the Pair object returned by base.LoadPageStateFromPersistenceMedium()
I now have a working solution. Test show a reduction of aroun 70% on the test page so I'm pretty happy with that.
Now that I have compression working I need to recommend that the next (first proper) Code Review has a focus on removing viewstate where it is not needed.
Thanks to eveyone who responded to my cry for help - saved me a few grey hairs there.