Tech Off Thread

13 posts

ASP.NET ViewState (flawed architecture?)

Back to Forum: Tech Off
  • zhuo

    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

  • cheong

    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?

    Recent Achievement unlocked: Code Avenger Tier 4/6: You see dead program. A lot!
    Last modified
  • zhuo

    cheong wrote:
    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?


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

    I agree that the problem i described is expected, but my point though is that ASP.NET probably should have implemented one hiddenText field per controls type of scheme, so the states of individual controls are loaded on the page independently, thus no issue with the problem described.

    In anycase Ruby on Rails doesn't even need such a thing as ViewState in order to retain state, but that might be because they have a simplified representation of html elements thus not requiring to store extra info related the ASP.NET controls.

  • cheong

    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)

    Recent Achievement unlocked: Code Avenger Tier 4/6: You see dead program. A lot!
    Last modified
  • blowdart

    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.

  • zhuo

    cheong wrote:
    
    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)


    I know that for both IE6 and Firefox, my app works fine and I've checked with one particular scenario where the ViewState is as big as 206kB and all postbacks works fine in both browser.

    It would still be nice to know if some of you out there has a solution to the ViewState problem.

    Any comments welcome.

    Smiley

  • JChung2006

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

  • stevo_

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

  • stevef100

    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

     

  • zhuo

    stevef100 wrote:
    

    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

     



    Thanks for that, I will look into it. This should be adequate for my purpose. It should also makes the user experience a lot more responsive.

    Cheers,
    James

  • zhuo

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


    Yes and I agree with the idea of ViewState, only that in cases where you want to perform bulk editing and updating (as is in my case) the ViewState causes problems.

    Which is why I am suggesting that ViewState should be encoded and decoded individually for each control, this way it gets rid of the problem with large ViewState while at the same time achieving what ViewState is useful for. Just an idea I guess.


  • bgard6977

    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.
  • JChung2006

    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.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.