Calling base Methods When Overriding Page Level Events - asp.net

In my code behind I wire up my events like so:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
btnUpdateUser.Click += btnUpateUserClick;
}
I've done it this way because that's what I've seen in examples.
Does the base.OnInit() method need to be called?
Will it be implicitly be called?
Is it better to call it at the beginning of the method or at the end?
What would be an example where confusion over the base method can get you in trouble?

I should clarify:
The guidelines recommend that firing an event should involve calling a virtual "OnEventName" method, but they also say that if a derived class overrides that method and forgets to call the base method, the event should still fire.
See the "Important Note" about halfway down this page:
Derived classes that override the protected virtual method are not required to call the base class implementation. The base class must continue to work correctly even if its implementation is not called.

In this case, if you don't call the base OnInit, then the Init even will not fire.
In general, it is best practice to ALWAYS call the base method, unless you specifically know that you do not want the base behaviour to occur.
Whether its called at the start or the end depends on how you want things to work. In a case like this, where you are using an override instead of hooking up an event handler, calling it at the start of the method makes more sense. That way, your code will run after any handlers, which makes it more emulate a "normal" event handler.

Although the official framework design guidelines recommend otherwise, most class designers will actually make the OnXxx() method responsible for firing the actual event, like this:
protected virtual void OnClick(EventArgs e)
{
if (Click != null) Click(this, e);
}
... so if you inherit from the class and don't call base.OnClick(e), the Click event will never fire.
So yes, even though this shouldn't be the case according to the official design guidelines, I think it's worth calling base.OnInit(e) just to be sure.

official framework design guidelines recommend otherwise
They do? I'm curious, i've always thought the opposite, and reading Framework Design Guidelines and running FxCop has only cemented my view. I was under the impression that events should always be fired from virtual OnXxx() methods, that take an EventArgs parameter

You probably are better off doing it that way, then this debate goes away. The article is interesting though, especially considering that the .NET Framework doesn't honour this guideline.

#Ch00k and #Scott I dunno - I like the OnEventName pattern myself. And yeah, I'm one of the people who are guilty of firing the event from that method.
I think overriding the On* method and calling the base one is the way to go. Handling your own events seems wrong somehow.

Related

Benefits of Implemention of both overridden OnInit() & Page_Init event handler?

I do have a small doubt regarding ASP.NET Page Life Cycle events. When gone through the coding of an application I came to see both overriding of OnInit() method and also Page_Init event. I thought both the approaches serves the same purpose and i saw mostly the implementation of overridden OnInt() only but not both. Most of the articles in the web explains about the better approach in these two and I know that generally overriding the OnLoad/OnInit methods is faster and also if you override OnInit and fail to call base.OnInit then the Init event won't be fired but no one explained what happens if we implement both. What does this situation means. Can anyone please help me regarding this. Thanks in Advance.
Page_Init is just a shortcut for calling the OnInit override they both do the same thing. Page_Init requires the AutoEventWireup property to be set to true because it tells the compiler to look at your code for certain methods like Page_Init or Page_Load and fire them, this video from Fritz Onion on pluralsight does a really good job of explaining it: ASP.Net 3.5 Pluralsight Course

best way to reference event arguments in asp.net

Best practices question.
While I was writing some event handlers, I ran into an issue where I as looking at the incorrect event (GridViewRowEventArgs) when I should have been looking at something else.
Now to solve my problem, instead of referencing the very specific event I was looking at, I just used EventArgs, which seems to catch any possible event. So, finally to the question; is there an issue with using EventArgs instead of the specific event? is it better to use the specific one for debugging issues? What is everyone's opinion?
Thanks
If a control is compliant then their event arg classes will always inherit from the generic ASP-provided EventArgs, which is why your approach works. Ultimately, if you don't need the extra information provided by the control through their own custom event arguments class then obviously you can dispense with using it altogether.
However, from a best practice perspective, my feeling is that it would be better to use the correct handler signature provided by the control, since that makes it predictable to people who might be working on your code and can't read your mind, but do have access to the the particular control's documentation.

When in the page lifecycle is the ViewState collection available?

When exactly is the view state accessible from the .Viewstate property of a control? From my observations, the closest event is on the Page.PreLoad event (at Page.InitComplete, Viewstate is still unavailable).
However, for controls that implement the IPostBackEventHandler interface the LoadValue() method is called and the .Viewstate collection is available (this occurs after Page.InitComplete and before Page.PreLoad).
Does anyone know of any additional events that can be used to know when Viewstate is available? Or any tricks (not excluding reflection on private/protected/internal members) that can be used to know if the Viewstate has loaded or not?
When exactly is the view state accessible from the .Viewstate property of a control?
After the LoadViewState method has been run.
Normally this means after the Init phase and before the Load and Handlers (e.g. "OnClick") phase. But ViewState is really complicated, so I highly recommend reading this excellent article to truly understand ViewState.
Since you can override the LoadViewState method, this makes a good place to put any of the kind of tricks you mention:
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
this.ViewStateLoaded = true; // or you could fire an event or something
UpdatePanelVisibility();
}
Of course, this does assume that you are using your own implementations of controls, which is not always the case.

What is the best way of subscribing to events in ASP.NET?

I've done some reading on SO, but didn't find the answer to my question.
As #Canavar points out in his answer there are 2 ways to subscribe to an event:
Declarative:
<asp:Button runat="server" ID="myButton" OnClick="myButton_Click" />
Code Behind:
myButton.Click += new EventHandler(myButton_Click);
I subscribe to events declaratively, but hardly ever use the "sender" and EventArgs in default event handlers. Most of the time I end up calling a method from the event handler.
Would it be better to subscribe to events using a delegate?
myButton.Click += delegate{DoStuff();};
Let me know if I'm over complicating things, and should stick to declarative event subscription, and calling my DoStuff() method from default event handler.
Your handler needs to match the event's specified params. If you use a delegate you will just be defining the same thing. Discarding the params seems like a waste since you might need them in the future for some reason. I can't think of any good reason to not want the parameters.
And an event handler is a delegate already :)
I personally use the declarative approach whenever possible. While neither the declarative nor imperative approach is really "better" than the other, both have their merits. For the most part, using the declarative approach means you have greater decoupling and more flexibility between page behavior and page content. If you, for whatever reason, need to change you're page content around, using the declarative approach gives you more leeway to do so without requiring a recompile.
That does not mean the imperative approach is useless. There are times when it is not possible to apply handlers declaratively. Namely dynamic scenarios. The imperative approach allows you to use code to create dynamic content and still wire up events. Use what fits the scenario best. There is no one proper approach, both have their niche.
My favorite:
myButton.Click += myButton_Click;
The EventHandler is not actually needed. Also, if you are C# 3.0, you can go lambda on it:
myButton.Click += (x,a)=>DoStuff(); // something like that.
But really, it isn't worth worrying about too much.

At what point should I call base methods of ASP.NET events?

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
}
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.
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);
...
}

Resources