At what point should I call base methods of ASP.NET events?
-
23-08-2019 - |
Question
In ASP.NET, if I override a page lifecycle event, should I call its base method before or after doing my work? Does it even matter?
protected override void OnPreRender(EventArgs e)
{
// My code goes here
base.OnPreRender(e);
// Or here
}
Solution
Yes you should care. Let's say for a moment that you need to insert a new base class in all of those pages. To me it's easier to just go ahead and call the base methods than have to do a lot of refactoring later.
Then again, maybe you don't need to do that.
EDIT
Based on the edit to the question here's some more info:
Yes, you should care. Sometimes you want the base classes method to fire before yours (in case of constructors), and sometimes you want it to fire after yours (destructors).
It may mean the difference between whether a property or object is available or not at the time your code gets to it.
OTHER TIPS
The "OnEvent" methods in the asp.net event model merely wrap the actual event calls (in this case, the "PreRender" event). So the only thing you need to decide is "do I need to call the event before or after I do my work"?
The answer is, it depends on what the code is doing as to if it should go before or after.
As another said, if it is constructor stuff it should go before. Destructor should go after. To give a more concrete example, if you have code that processes the page and loads content, fills drop downs, and fills labels and such then you would want that to happen before any code that looks at what is pre-populated and determines visibility or business rule logic that has to do with the data on the page.
I think it's a good idea to call them just on principle. It may be true that in the framework version you're currently using there's no code in the base class methods, but who knows about future versions. Also, separation of concerns would dictate that code you write that derives from Page not assume the Page class doesn't do anything but raise the PreRender event in its OnPreRender method.
There is no single rule. I can provide you an example. My ASP.net webapp uses a NHibernate transaction opened by the master page and commited/roll-backed by it when the page ends.
Well, I MUST initialize the transaction as early as possible in the OnInit method (Master has no OnPreInit like Page), otherwise user controls cannot access the transaction until Page.Load.
The same rule applies for commit. Controls may want to update objects in the last phases of their life-cycles, then I must close the transaction as latest as possible in the Unload method, or even in the disposer!
So... in my case...
void OnInit(EventArgs e) {
transaction = session.BeginTransaction();
base.OnInit(e);
}
void OnUnload(EventArgs e) {
base.OnUnload(e);
try{
transaction.Commit();
} catch {}
}
void OnError(EventArgs e) {
base.OnError();
transaction.Rollback();
}
I would suggest you a general rule: if your page's design contract involves creating and destroying resources to be used by controls between a certain event range (ie. after Load and before PreRender), init the resource as late as possible before the event is fired, and destroy it as early as possible after the final event is fired
If you're going to call the page base methods anyway, you can use
protected void Page_PreRender (object sender, EventArgs e) {...}
rather than
protected override void OnPreRender(EventArgs e) {
base.OnPreRender(e);
...
}