Event Handler doesn't fire immediately upon postback?

J

John Kotuby

Hi guys,

I am converting a rather complicated database driven Web application from
classic ASP to ASP.NET 2.0 using VB 2005 as the programming language. The
original ASP application works quite well, so at times it is tempting just
to port parts of it over mostly as-is. In fact, one MSDN article I read
suggested using straight HTML wherever possible to make the app more
efficient and less resource demanding.

On one page there are 2 Dropdown listboxes written in Classic ASP where we
see onchange="Filter()", referring to a clientside JavaScript function that
simply posts back to the originating page with a querystring name/value pair
of FilterIt="Y". The original page load runs an unfiltered SQL Server query
to display records. When a user makes a selection from the dropdown list,
the postback page looks for Request("FilterIt")="Y" and then proceeds to
re-run the query with the filter selected by the user from the dropdown. It
works quite nicely. (The original classic ASP)

However, I have decided to use the Server DropDownList control to more
cleanly separate the SQL query from the actual page generation code. When an
event is captured clientside, the event handler fires immediately. Therefore
I logically deduced that the same would be true of a server side event
handler immediately upon postback. At least, that is what I hoped would
happen.

My plan was to set a Public variable FilterIt to "Y" in the even handler for
either of the dropdownlists. Here is an example of the code that calls the
handler from one of the controls:
-------

<asp:DropDownList runat="server"
ID="catList"
OnSelectedIndexChanged="mlrList_SelectedIndexChanged"
AutoPostBack="true">
-----

In the handlers I set the Public variable FilterIt="Y" and also send out
some debugging code, and I do not reset the value of FilterIt before the
Page_Load event.

-----
Protected Sub catList_SelectedIndexChanged(ByVal sender As Object, ByVal e
As System.EventArgs) Handles catList.SelectedIndexChanged
filterIt = "Y"
'*** JPK debug
Response.Write("2 catList_Selected: cat=" & catList.SelectedValue.ToString()
& " filterIt=" & filterIt)
Response.Write("<br/>")
'*** JPK debug
End Sub
-----

Note how I placed a number before the response text to indicate what I
expect to be the firing order of events. The other dropdownlist event
handler has a 1 preceeding the Response text.

Now in the GatherRecordsets() Sub called from Page_Load I make my SQL query
calls. I understand that is the suggested location for gathering data. Here
is what I have done prior to assmebling the SQL query string:
-----
If Not Page.IsPostBack Then
filterIt = "N"
mlrFilter = ""
catFilter = ""
Else
mlrFilter = mlrList.SelectedValue.ToString()
catFilter = catList.SelectedValue.ToString()
End If
'*** JPK debug
Response.Write("3 GetRecordSets: filterIt=" & filterIt & " mlrFilter=" &
mlrFilter & " catFilter=" & catFilter)
Response.Write("<br/>")
'*** JPK debug
-----
I do Not set filterIt="Y" on every postback, because not every postback is
requesting a filter.
To my surprise, after selecting a filter category from the dropdown, this is
what I see returned at the top of the page.
-----
3 GetRecordSets: filterIt= mlrFilter= catFilter=electronics
2 catList_Selected: cat=electronics filterIt=Y
2 catList_Selected: cat=electronics filterIt=Y
-----
It appears that the Page_Load event is firing before the event handler. I am
correctly identifying the PostBack because the variable
"catFilter=electronics" is holding the selected value. But even though
"FilterIt=Y" is correctly set in the event handler, since the event appears
to fire after Page_Load, that value never gets to my SQL query.

Also, it seems that the event handler is firing twice. Very strange.

Sorry about the lengthy post, but I wanted to be clear about what is
happening. Is this the intended behavior envisioned by the ASP.NET
designers, such that I have to program a "work-around" to obtain my
objective? Or am I doing something wrong? When I was reading about page life
cycle event firing order, I didn't notice that event-handlers took a back
seat to other events.

Thanks to all for any and all input ...
 
K

Kevin Spencer

Hi John,

It's not surprising that you're having some difficulty adapting to the
ASP.Net programming model, coming from Classic ASP, which is entirely
procedural. Hang in there. It gets easier.

First of all, you may find the following chart helpful:

http://www.eggheadcafe.com/articles/20051227.asp

It describes the ASP.Net 2.0 Page LifeCycle. It seems a bit complicated, and
in fact, it is, but you don't need to know everything about it at this time.
The complexity comes from a combination of the "disconnected" nature of HTTP
and the event-driven programming model, combined with a hierarchy of
Controls within Controls in the Page, which is, itself, a Control.

Because of the "disconnected" nature of HTTP, each PostBack requires that
the entire Page object hierarchy be reconstructed, repopulated in its'
previous state (prior to the PostBack), and only then does the Page (and
everything inside it) handle Events. If you think about it, this is
perfectly logical under the circumstances. It's just like the "conventional"
event-driven model, with the exception that in an HTTP context, everything
must be restored to its' pre-Event condition before the Events, which change
things, are processed.

Now, the chart is very useful, but let me simplify the explanation regarding
your immediate task for you. The basic process goes like this (and is
recursively passed from the Page to the Controls in each case):

1. Init - Initialization. This is where the Controls begin to be re-created
from scratch. All necessary settings are loaded in preparation for the
re-creation of the previous state.
2. Load ViewState - ViewState (previous Request state) is in a hidden form
field, and contains the previous client-side (from last Request) state of
all the Controls. It is read from the Request and loaded into memory, for
use in comparing current state of the Controls to previous state.
3. Process PostBack Data - This is where the data that is currently in all
of the Controls is loaded from the Request. This is necessary for the
Event-handling process, as "change" is determined by comparing the previous
client-side state to the current client-side state.
4. Load (Page_Load in the case of the Page) - All Controls are initialized,
and restored to reflect the client-side data.
5. Send PastBack Change Notifications - Here is where client-side Events
that cause a PostBack are raised, such as the OnSelectedIndexChanged Event.
6. Handle PostBack Events - Here is where the Event Handlers for the
PostBack Event are executed. The server-side state of the Controls are
changed.
7. PreRender - The output of the Controls is adjusted to reflect the current
server-side state of the Controls.
8. Save State - The ViewState is overwritten, to reflect the current
server-side state.
9. Render - The Response output is written for the entire Page.
10. Dispose
11. Unload

--
HTH,

Kevin Spencer
Microsoft MVP

Printing Components, Email Components,
FTP Client Classes, Enhanced Data Controls, much more.
DSI PrintManager, Miradyne Component Libraries:
http://www.miradyne.net
 
J

John Kotuby

Thanks Kevin,

That is the most straight forward explanation of page events that I have yet
read or heard. I found a chart on page 870 of Professional ASP.NET 2.0 from
Wrox publishing that was quite helpful. It got me past my immediate problem
since I moved my SQL Server queries to the LoadComplete page event which
according to the chart directly follows the RaisePostbackEvent phase. So far
that is working for me without any adverse consequenses.

But your explanation of "loading the Page" (Page_Load) as returned from the
client is what made the lightbulb go on. At that point the server can then
make its comparisons and work with the PostBack event handlers.

It seems like such a waste of resources to me sometimes to use controls like
the ASP:Calendar forcing a round-trip to the server just to grab a date
value. I still prefer to do as much client-side processing as possible
before making a call to the server. Thus I use a JavaScript calendar.
However, the concept of CallBack is something else (when I'm ready for it,
I guess ;-).

But I suppose if the browser caches most of the page then minor changes
following a postback can load fairly quickly. I am also seeng the need to
learn how to make the pages as "lean" as possible in terms of carrying
excess viewstate information, but I don't have enough of a handle on the
concepts to where I feel ready to strip things out.

Maybe somebody else will profit from this conversation also... hope so.

Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top