views:

239

answers:

6

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
}
+4  A: 

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"?

BC
Usually the answer is "it doesn't matter"
BC
+5  A: 

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.

Chris Lively
+1  A: 

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.

Mike Powell
-1: "It may be true that ... there's no code in the base class methods". No, the OnXxx base methods fire the corresponding event, and you can't assume no-one will be handling the event.
Joe
If you read my answer a little more carefully, you'll see that I'm in fact recommending that he NOT assume it's safe not to call the base class methods. You're taking the words "no code" too literally.
Mike Powell
+1  A: 

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

djechelon
A: 

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);
   ...
}
Iain Ballard
+2  A: 

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.

hyprsleepy