Tuesday, May 6, 2008

Event Order

Well, it's time to start off with that old ASP.NET standby, the order of events in the webpage. Now, we've all seen the pretty diagrams explaining every event in excruciatingly verbose detail, so I'm going to try to boil it down to the essentials. What do you absolutely need to know about the order of events, and more importantly, what difference does it make to you?

If I had to give the absolute minimum description, I'd say that there are three principal stages of an ASP.NET page - Init, Load, and Render. Init is where the controls are created and placed on the page. Load is where the controls' default values are populated from Viewstate. Render is where the HTML of the pages is generated. Beyond those three stages, there's another important detail that I feel gets lost in the shuffle sometimes - control-level events such as button clicks are handled between Load and Render.

So, what all of does this mean for you? There are a couple of takeaways. First of all, since the Init phase creates the controls on the website, don't expect to be able to reference them in PreInit, since they're not there yet. This limits the usefulness of PreInit, but it does make PreInit a good place to put logic that relies strictly on server session or other items not found in controls. For instance, I placed my login check in PreInit. The login check uses server session to determine if the user's logged in or not, and if they are not, they get sent to a login screen. I felt that putting the login screen in PreInit saves a bit of time, since I don't have to load all the controls unnecessarily.

More importantly, since control-level events come between Load and Render, if you're setting the values of controls yourself, you need to do so in PreRender. If you do it before that, then your control-level event will get the values that you just set, NOT the values that the user had actually posted. This means that things like the Text property of text boxes, the SelectedValue property of dropdowns, etc. will not work. You can work around that by using Request.Form on everything, but there's no reason to do that if you don't have to. Conversely, if you're dynamically creating your controls from scratch, that needs to be in Load. If you do it in PreRender, then the event handlers won't be set up by the time it tries to process control-level events, so your handlers will never get called. The result is that you click a button and nothing happens. So yes, it's annoying to dynamically generate a page in a two-step process like this, but that's the way you have to do it. If it's really a pain to split up the process into two steps, I'd recommend doing everything in Load and using Request.Form in your event handlers.

So hopefully that helps clear up event order and what it means to you.

No comments: