Thursday, October 25, 2007 10:35 AM
Understanding what Page.RegisterRequiresPostBack does
I recently received a comment in my Truly Understanding ViewState article about the "ArrayList of controls in the control hierarchy that need to be explicitly invoked by the page class during the raise postback event stage of the life cycle." Such is the 3rd entry in the master Triplet that makes up ViewState as a whole.
It was a very excellent question, and in some quick searches I don't see any really clear topics dedicated to answering it, so I decided to answer it with a blog post rather than bury it at the bottom of 100 comments. You can read the comment here.
To understand why this method is needed, lets walk through what happens when you use an ImageButton.
When you click on an html element of the <input type=image> variety, what is added to the form collection sent to the server is not what a normal button sends. A normal button sends the key/value pair "id=value". But an image submit sends "id.x=##&id.y=##". It sends 2 values, the x and y coordinates of the location of the image you clicked.
This means the KEY of the submission will not match the ID of the control. Normally, ASP.NET matches keys to their control IDs, and is able to find the control directly with FindControl() (which also has the indirect effect of calling EnsureChildControls). But it won't find a control named "id.x" or "id.y", so that ImageButton will never be notified of the postback data it generated.
All is not lost! RegisterRequiresPostBack comes the rescue. It tells asp.net to notify the control of postback data regardless of whether the form collection contains an entry for it. ImageButton can now happily look for "id.x" and "id.y" in the form data, and raise its click event if it is found.
Now why is there a list of controls that call RegisterRequiresPostBack in ViewState of all places? Because when you call RegisterRequiresPostBack, you're doing so for the next request not the current one. You're saying, "when what I'm rendering right now is posted back, I want to be notified." So ASP.NET needs to maintain the list of controls in ViewState so it can do so on the next request.
Some people have complained that even when they disable ViewState for the entire page, they see ViewState in their page. This is one of the reasons for that. It is simply required for the controls to function, it cannot be turned off.
The humble CheckBox
Another control the calls RegisterRequiresPostBack is the humble CheckBox control. When you post a form, any checked checkboxes are added to the form collection with "id=value". However, and quite unfortunately if you ask me, unchecked checkboxes add NOTHING to the form collection.
Ok -- so a CheckBox knows it is checked if its post data key exists, and unchecked if it is missing, right? Nope, sorry, that simply won't do. What would happen to a checkbox that is first created during a postback? For example, a checkbox within a databound control that has just been databound? How does that CheckBox know whether it is unchecked or has just been born into the world, err, page? The only way to know the difference is RegisterRequiresPostBack. If not for that, all checkboxes first created during postbacks would always start off unchecked, even if they were databound or declared to be checked.
Open up reflector and find the Page.RegisterRequiresPostBack method. Use the analyzer to find all the controls that call it. Try to understand why each of them needs it. I assure you, they all have good but distinct reasons.
Filed under: .NET, ASP.NET, ViewState