Events, Pages, and Statelessness

The ASP.NET control framework seems fairly well put together on the whole. I like the fact that they are able to use the standard event/delegate mechanisms to handle user input events from the browser. But the system is a little fragile. Its easy to make changes to your code that seem harmless enough, but cause everything to break. This seems particularly true with the event dispatching code (the stuff that receives the HTTP requests from the browser and maps them back onto events and controls). The root of the problem is that the event framework assumes objects with state and web interactions are inherently stateless. So, in ASP.NET, the external appearance is that you create a page, link up some events with handlers, get the page rendered out to the client, and then when the user clicks on something, the event fires and the handler gets called. It seems as though the page object is there for the whole time, remembering what events are hooked up to what handlers, and potentially lots more interesting state.

Of course, that's not the way it works. Once the page is rendered out to the browser, its thrown away. Keeping it around would be bad for performance because the user might never actually click on anything, and we'd be sitting around with this orphaned page object back on the server. You could try and get around this with time-outs and caches and the like, but the simplest solution is just to get rid of the page once its been rendered.

So, how do all those events get dispatched to the appropriate handlers? ASP.NET re-creates the page when the the user's HTTP request is sent to the server after they have clicked on something -- they call this a postback. And herein lies the fragility of the system. If you don't re-create the page appropriately during the processing of postback, then ASP.NET may not be able to dispatch the events appropriately. For example, in one situation I was dyanamically creating ID's for some controls. At one point I had the code so that the ID's generated on the postback were not the same as the one's when the page was rendered. And all of the suddent, I wasn't getting events anymore. And although this particular problem may not crop up in reality much, I've run into the same problem in numerous guises over and over again. If you just drag and drop controls onto a page, you're probably not going to get bit. But if you're dynamically allocating controls, or generating HTML dynamically, it seems all too easy to break the system in this way. And it doesn't seem to do a very good job of helping you diagnose this problem. In almost all cases, the request just silently fails and you end up looking at the same page on the browser again.