Page execution order hints

Posted by Mike Dwyer | Filed under

We all have memorized the page life cycle of an ASP.NET page right?  Ok, so maybe not, unless we are in a job interview answering trivia/book questions by the interviewer.   So, I am not going to get into that as there are more than enough resources to help you there.  What I do want to address is some common areas where knowing the order of execution can be very important to avoid some common pitfalls from code I have worked with, as well as my own in the past.

We all know to begin our work in the page_load section of the page.  We know this is the starting point for most of us.  From there we can execute other procedures to build the page.  Now, first of all, do not put all your code in the page_load.  Not only does it get hard to follow at a high level what is happening during load, but you will find almost every time that you will have to move it, or start putting if statements around it making the page_load even harder to follow.  Why do I say that?  Because of the postback.

Ok, so you are following me here and you are telling me you use the isPostback to determine what to do if the user has made a postback.  You use the old:
 if (isPostBack) {
     executePostbackStuff();
     loadDropDowns2();

} else {
     executeNonPostbackStuff();

So far this is very simple.  If the page is a postback, I need to load a drop down list (from a database).  Now, let's say you add a linkbutton to your page, and you create an event for that linkbutton:
protected void linkbutton_Click(object sender, CommandEventArgs e) {
    removeItemFromDB(); //removes item that is used in dropdownlist

What's wrong with the above? Well, the page_load gets executed before the linkbutt_click event.  So, even though you remove the item from the DB that the dropdownlist is binding to, it will still be in the list until the next refresh.

The solution you say is the following: 

protected void linkbutton_Click(object sender, CommandEventArgs e) {
    removeItemFromDB(); //removes item that is used in dropdownlist
    loadDropDowns2();  //recreate dropdownlist

}

That is great, you have solved your problem in that you will just call the function to rebind the dropdownlist.  However, you have created a problem as well.  The problem is, that dropdown list will be bound twice on load.  Once in the page_load (from the postback), and a second time in the event.  Most times, you may not notice this, but if you are binding a large dataset to a repeater or gridview, your pages not only will load slow, you will be putting unnececsary work on the database server.

The solution in situations like this is to track which item caused the postback, and handle it accordingly, or follow below.

A second point I want to make here for beginners is, in your page_load you may have something like:

protected void Page_Load(object sender, EventArgs e) {
     loadDropDowns();

}

This of course will rebind the dropdownlist every time the page is loaded.  Keep in mind, you do not need to do this, and again only puts unneded overhead on the servers.  The first time the dropdownlist is bound, it will be stored in the viewstate and recreated on its own.  In case of postback, the page will still display the populated dropdown list.  So, this is what you will want for efficiency on your pages:

protected void Page_Load(object sender, EventArgs e) {
if (!isPostBack)   loadDropDowns();

}

This will work for any databound items that do not change between postbacks.  If some items do require a change, i.e. the linkbutton example above, then in the linkbutton event, call loadDropDowns(); which will then refresh the dropdownlist for you.

My advice for beginners and even intermediate developers, is to put breakpoints on all your data calls to see how many times they are called.   Each, on almost all occassions, should only be called once.  Try loading your page, go through all postback methods (i.e. form submit, linkbuttons, etc) and see if your breakpoints are hit multiple times.  If they are, you have some work to do.

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

custom Auto Complete Extender Extended

Posted by Mike Dwyer | Filed under

I have to be honest, I was a pretty big fan of the auto complete extender in the ajaxcontroltoolkit.  But, it got me thinking, which generally results in bad things happening.  I have some searches that search multiple fields in a database, for instance, different name fields (i.e. "To" and "From").  So, with the original extender, it would be difficult to bring the results since you really only had one column.  The result would be a one column list and the user would not know what field the result is coming from.  So, I thought it would be nice to bring back a column header.  Then I figured, while I am at it, to return a string delimited by "~~" which represents table columns and have the javascript build a table for me.  So, the result is the autocomplete will show multiple columns (much like a gridview) with column header, and the user can easily see the different results that match what they are typing.

 

Phew, that was pretty cool.  But the width of the autocomplete div was all over the place.  So, I had to add a property so you (the developer) can resize the div width. 

 Now we are really getting somewhere.  The next step was to navigate through the table structure with both keyboard and mouse.  With the keyboard, you can use up and down to go through.  When you select the row you want and hit enter, the autocomplete will fill in with the text from whatever column matches what you are typing.  In the example, you will see text to tell you to type "223".  You will see three rows displayed.  Cursor down and hit enter.  You will see the first column text will fill in.  Instead, type in "Micha" and cursor down one row where the first name column has Michael and hit Enter.  This type Michael will automatically fill in.  Originally, my header row got in the way and the user was able to cursor down and select the header row.  Well, that is just silly, so I added another property to let the extender know if there is a header row. 

Can it get any cooler?  It turns out that yes, it can get slightly cooler.  When the list drops down, use your mouse and click any of the columns and you will see the autocomplete fill in with the value from the column you clicked.

I built the sample project quickly, I believe the solution file is actually in the customAutoCompleteExtender folder.  The second project is website which contains the default.aspx sample page and the ajaxServies.asmx/cs files needed to return results.  You can easily have the result populated from a database as I did.

customAutoCompleteExtender.zip (967.79 kb)

Currently rated 4.0 by 2 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5