Posted By: zhuo | Dec 4th, 2006 @ 7:39 PM
page 1 of 1
Comments: 12 | Views: 13454

I've encountered an ArgumentException in ASP.NET and it has been a question that sort of stuck in my head for a while now.

I know the likely cause of this ArguementException is a ViewState issue. I think ViewState is the cause because the ASP.NET page in error loads a datagrid of many editable elements, all of which require ViewState to retain states. In cases where many rows are loaded, it may take a while for the whole page (including the ViewState) to load. If the user is impatient and clicks on another button on the page, the page errors out because an incomplete ViewState has been posted back thus can't be decoded properly.

I can't really see anyway of fixing this other than to try to reduce the latency of the loading process or some how reduce the use of ViewState whilst still being able to retain state somehow.

Isn't this (ViewState) a major flaw with ASP.NET architecture? I.e if ViewState information had been associated with individual elements/controls on a web page instead of being put into a single chunk of Base64 string then the problem described above wouldn't really be a problem in majority of the cases. Ruby doesn't have this problem, maybe ASP.NET can learn from their implementation?

What do you guys think?

James

I'll say that it's expected.

You know, the viewstate is stored in a hiddenText element which is 1024 byte in Mac and 4096 byte in other browsers of other systems. If you have too many controls and you don't selectively enable the viewstate for each item, you're destinated to burst the limit.

But is there anyway to tell ASP.NET to use Session instead to store "state" data?
zhuo wrote:


I might be wrong, but what you've said about size limit could not possibly be true based on experience.


No. The size limit for the hidden input control is documented. And the most frequently seen exception report when I join this company is "Invalid Viewstate" exception on Mac_PPC clients running IE5 for Mac. (The exception is cause because the viewstate is trimmed by the browser hence become corrupted). It takes me a good week to disable disable viewstate of individual pages.

It could be because of our business nature (my company is running printing business), but you'd be surprise how many exception report I've seen because of this.(About 30% of our customer still uses iMac running Mac OS 9.X)
blowdart
blowdart
Peek-a-boo
cheong wrote:


But is there anyway to tell ASP.NET to use Session instead to store "state" data?


You can hand role it; over ride SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium. Then you can store it in session state, the asp.net cache, wherever.

You'd need to call RegisterHiddenField to add the unique reference you used in SavePageState;

RegisterHiddenField("__VIEWSTATE_ID", myUniqueKey);
RegisterHiddenField("__VIEWSTATE");
Then in LoadPageState simply retrieve return your saved ViewState.

It's a poor craftsman that blames his tools for his mistakes.

stevo_
stevo_
Human after all
I wouldn't say its a 'flawed architecture' at all, it was designed with its purpose, not to rely on the session...
stevef100
stevef100
DaddyO

look at the SessionPageStatePersister for a way to keep viewstate server side that is inbuilt into asp.net 2.0. The client recieves a simple viewstate key which is used to lookup the viewstate server side

 

I think there are two issues being confused here:

1. From the original post (and personal experience) there is an IIS/aspnet_isapi.dll issue here. IIS is interpreting a socket disconnect as end of stream, and therefore violating the HTTP protocol. HTTP has a header which determines the number of bytes in the body. If the socket is disconnected before receiving this number of bytes, IIS should determine that it is a bad request, and never forward it on to ASP.NET. When the error is:

Invalid length for a Base-64 char array

The client disconnected. ---> System.Web.UI.ViewStateException: Invalid viewstate.

Invalid length for a Base-64 char array

It doesn't sound like that is the case.



2. A good craftsman can definitely blame his tools if they don't perform to spec. (at least until he discovers the problem finds a work around!). The .NET framework is presented as a black-box, a layer on top of which we are to build applications. It is not the job of application code to ensure its foundations work properly. ASP.NET knows the user_agent, and should limit the viewstate to a size compatible with that browser. If the viewstate exceeds what a browser can handle, it should either break it up into multiple form elements, or throw an exception server-side on rendering.

AFAIK there is no way to check the size of the viewstate after encryption and BASE 64 encoding (aside from writing an HTTP Module), so there is no clean way for an ASP.NET app to even know whether its viewstate will cause an error.


Until such issues are resolved it seems like best practice is to implement server-side paging in datagrids, watch the number of controls on a page, and generally use common sense to prevent overflows. I must say with IE 6 & 7 at least, I have built some pretty large viewstates and never seen this problem occur, although I wouldn't doubt it could happen on older browsers.

Maybe before you go off and criticize ASP.NET "ViewState architecture" that you should wonder just what you are doing to bloat your ViewState so much in the first place and act accordingly.  Bad code is bad code no matter if it is written in C# or Ruby.

page 1 of 1
Comments: 12 | Views: 13454
Microsoft Communities