Page_Load is Evil

We have all seen it, sitting there, waiting for code, when we first open a page in code view. The handy Page_Load(object sender, EventArgs e) method:

Page Load is Evil

Well, friends, I am here today to tell you that this method is evil. That’s right, this nice friendly delegate is actually evil. And here is why:

  1. It encourages doing everything when the page loads by raw convenience. And doing all that inside this one method. I have seen 300+ line Page_Load methods on an alarmingly regular basis. I have seen entire websites programmed into Page_Load methods. Probably 95% of the ASP.NET code running in this world lives in a Page_Load method.
  2. It obfuscates page life-cycle from inexperienced developers. Too many just use Page_Load because that is the only way they know to get code to execute when a page is requested, save handling postback events.
  3. Page_Load is too late to do some things, like add controls, confusing some developers.
  4. Page_Load is too early to do some things, like deal with button clicks, confusing some developers.
  5. From a maintainability perspective, it makes it difficult to move actions into different places of the page-life cycle when necessary.

OMG! THAT IS EVIL! What am I to do!?!?!?!

So, you are not to use Page_Load, what is one to use? Well, one should just wire up page events manually in the constructor. Like so:

Event wireup is good.

Why is this a the superior method? First, your actions can be logically grouped into their own methods, rather than having them live as 20 line segments of a monster Page_Load() method. Second, and most important, is that you can easily move a method around in the page lifecycle by changing the name of the event it is attached to. Finally, you are left with much cleaner, much more intelligible code.

Happy coding and kick it on DotNetKicks.com it if you like it.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • chrisb

    Its been a while since I’ve actually touched any .aspx stuff but gotta say thats a pretty decent idea.. even if only so the junior devs can keep up with and understand how the code is working its gotta be a plus

  • ikeo

    Question for you Mr. Barnett …
    Based on your post what would be appropriate to put in the Page_Load function?

  • Anonymous

    > Probably 95% of the ASP.NET code running in this world lives in a
    > Page_Load method.

    That is disgusting, if its true for the majority of the population on this platform; that isn’t development… I don’t know what you could describe it as?

    God… How would you test it huh? Huh?

  • wwb_99

    @ikeo: Page_Load itself: nothing, delete it. Your custom load delegates: anything which is appropriate. Such as databinding your grids.

    @anon: I probably overstated the case. But 99% of the asp.net examples in this world do work out of the Page_Load (or OnLoad). It really is a holdover from the MS’ VB6 dark days encouraging developers not to worry about the man behind the curtain.

  • Payton Byrd

    This isn’t a technology problem. The Page.Load event is not evil, there are a lot of things you should be doing here, like loading preparing the statefullness of your page after controls are created and before UI events are processed. Would you prefer loading data in Page.Init instead? That would be ludicrous.

    No, the problem is that people hire ASP/JSP/PHP developers off the street, say “Go write an ASP.Net page, it’s just like ASP” and then don’t do any kind of follow up to make sure they follow the best practices for the platform. What’s evil is the kind of apathy that management has for doing things correctly and not following through on promises to train people correctly.

    Payton Byrd

  • Rodel E. Dagumampan

    as long as you use AutoEventWireup set to true, for me using Page_Load events and/or overriding these is perfectly fine with me. Now maybe I want to ask you if you want to put code on Page_Load event but should not call the base implementation of Page_Load on its base class? What you think?

    Rodel E. Dagumampan

  • Anonymous

    I like your approach, it adds some usefull transparancy to the life cycle.

    It seems to me that the root problem is that the page life cycle isn’t given the respect it deserves in tutorials and documentation.

  • http://www.dotcomwebdev.com chris ward

    Hi Wyatt,

    I would desperately like to see more on this subject!

    I’ve tried reading up on this before, but from a designer/programmer’s point of view it’s sometimes difficult to get my head around the order of events or their meanings.

    Sometimes the order of events has caused me problems (especially with dynamically created controls and their respective events), so yes, it would be great if you could follow this up and clarify the concept!

    Thanks :)

  • http://www.sitepoint.com/ Kevin Yank

    The lack of press that ASP.NET’s page lifecycle gets frustrates me to no end. Thanks for covering this pet peeve of mine, Wyatt! :)

  • ijoxley

    If you use explicit binding for page events, don’t forget to set AutoEventWireup="false" in your @Page directive. Otherwise you may end up with the method being called twice.

  • henke

    I started reading this article thinking there actually would be some interesting content, considering the very alerting headline. I guess I was wrong. Just some MS-bashing going on as usual.

    It’s a legit fact that you can’t do it all during Page.Load, and as ijoxley says, the programmatic event registering you’re doing, could cause things to happen twice if you have either both a method called Page_Load and wire that up or if you are using an inherited base page from which all sub pages inherit that has a Page_Load method.

    What I’d then be a lot more interested in would be your take on the MVP pattern, in which case, all you really do in the handler for Page.Load is to wire up the views. From where I’m standing the MVP doesn’t give you much considering the time, except the possibility to unit test… So then the question is how you wire up your pages in an (enterprise) system… I haven’t quite answered that fully, myself… Now I’m simply using Master pages and base classes to the page and communicating to services and to the application layer and even to the data access object layer if it’s uncomplicated…

  • Adam Toth

    As a lead ui developer that oversees a team, I have to disagree with this approach here. Insulating the devs from the page lifecycle with friendly method names will only worsen the situation, there are too many other situations where the lifecycle can bite you in the ass if you don’t know it like the back of your hand.

    Before I hire anyone, I make all my developers take a list of common events in the lifecycle, Load, Init, Button Click, PreRender, etc and arrange them in the order in which they fire on the page. If they can’t do that, then no hire, period.

    LoadData doesn’t tell me anything about whether or not UI control events fire before or after it. It also doesn’t tell me if ViewState has already been loaded yet or not. Additionally, when using declarative data source controls that do their own databinding when they see fit (sometimes after PreRender, sometimes before Init), you aren’t going to have data loading code, in which case that methods makes no sense. Or, sometimes you need to databind in Init on a postback so that ViewState can correctly determine what has changed since a postback.

    It’s much better to get everyone familiar with the lifecycle using the standard Page names. I have a page template that my devs use that has each page event xml-commented with notes such as “Page_Load fires after viewstate is loaded, but before common control events are fired”.

  • ijoxley

    An approach I tend to favour is a combination of the two: I leave the event-handlers as Page_Load, Page_Init, etc. but within them call methods such as BindData(), AddDynamicControls(), and so on.

    For example:

    private void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            BindData();
        }
    }

    Also, I think this offers more flexibility as BindData() is defined without any parameters. It can therefore be called anywhere in the page e.g. in a ImageButton‘s Click event-handler after deleting an item from a GridView, which would not be quite so straight forward to do if BindData was defined as a event-handler for the PreRender event: it would need a sender object and an EventArgs object i.e. BindData(object sender, EventArgs)

  • Tryst

    Adam, I am about to commence work in the ASP.NET field, and would find that Template you mentioned extremely useful. If poss, could you send it over to trystano at aol.com? Would help me a great deal in understanding all this Page Life Cycle stuff.

  • Soteriologist

    This’ll tell you everything you need to know Tryst… and it’s made by Microsoft ;-)

    http://msdn2.microsoft.com/en-us/library/ms178472.aspx

  • Theodor Zoulias

    Load += new EventHandler(DoThis);
    Load += new EventHandler(DoThat);

    Which will be invoked first, DoThis or DoThat?

    Nobody knows for sure!

  • Urm

    Eh yeah .NET PROPRIETARY MS GARBAGE!!!!! MS IS EVIL, NOT JUST SOME SILLY PAGE_LOAD!!!!

    PHP WOOOO!!!!! MYSQL WOO!!!!!! .NET urm no.

  • Darrell

    Probably 95% of the ASP.NET code running in this world lives in a Page_Load method.

    Nonsense! I certainly agree there are a lot of programmers out there that just dump everything in the page_load but to make a ridiculous generalization that 95% of the asp.net code lives in the Page_Load is a gross overstatement.

  • pfarrell

    Nice post. I love the totally unscientific 95% reasoning. While I like to think that most coders aren’t generating shit like that, I can’t fail to look at the code I’ve inherited. Plus, add to fact that consultants tend to want to write unmanageable code for job security… You may not be as off as Darrell thinks

    check out patf.net

  • Anonymous

    > Probably 95% of the ASP.NET code running in this world lives in a
    > Page_Load method.

    Bullshit.

    > I have seen 300+ line Page_Load methods on an alarmingly regular
    > basis. I have seen entire websites programmed into Page_Load
    > methods.

    You are amongst idiots. Escape!

  • RottenApple

    Page load is not evil. I guess the in house develoment team you lead is incompetent.

  • David

    Page_Load is not evil, it is just open to often misused..

    -David.
    http://www.davemckay.co.uk

  • inv

    I totally agree with you! I consider myself a good programmer, but as far as asp.net goes i often feel like an idiot.

    Despite of this, I’ve managed to create an enterprise search engine frontend that looks really good and works without flaw. And as much as it hurts me to admit it, I have to say that a lot of mye code is in the page_load method! You can accomplish a lot by putting all your stuff there, but its going to cost you a lot in the form of time and hacks (maintainability).

    I think c#.net is A+ in terms of usability, while asp.net is on the other side of the scale. I also think that this is something MS should take seriously, because the day a better high level framework for web development comes around…i’m making the switch!

  • Anonymous

    Adam Toth you are idiot. With such a strategy you should fire yourself first fuc&ing snob. To understand the events sequence it only takes 15 minutes in debugger or 5 minutes on internet for someone who unluckyly gets involved in ASP.NET Why would i to trash my brain w/that bullshit produced by microsoft trying to remember that crap that will be a brand new crap year later?

  • Anonymous

    Yes, knowing when to use page events is VERY difficult when you don’t know how to read.

    http://msdn.microsoft.com/en-us/library/ms178472.aspx

    It encourages doing everything when the page loads by raw convenience. And doing all that inside this one method. I have seen 300+ line Page_Load methods on an alarmingly regular basis. I have seen entire websites programmed into Page_Load methods. Probably 95% of the ASP.NET code running in this world lives in a Page_Load method.

    This statement along with statements 2-4 can be resolved if the developer takes a few minutes to LEARN how things work before slapping code down and shipping it. (300+ line functions in general deserve a good jam session with a book: see Code Complete by Steve McConnell and Refactoring by Martin Fowler)

    Most of this “article” equates to this statement: “A hammer is evil because it is bad at putting screws in a board.” Don’t blame a tool for the ignorance of the masses.

    Reading is fundamental.

  • harsha

    iam satisfied not to use Page_Load … now what … how to make things work? can someone paste code snippet showing the way it should be done (using constructors or something else). Thankyou