Uncategorized

ASP.NET incorrectly raises a CheckChanged event for a read only checkbox

Here’s another interesting one: we had a .aspx page with some controls on it, and one of those controls were a CheckBox; upon a postback, we were trying to set the CheckBox as readonly. What we obtained is that ASP.NET incorrectly raised a CheckChange event even though none clicked on the CheckBox and so that event was not expected to fire; it seems as if the viewstate handler incorrectly detects a change to the checked value.

First of all, Internet Explorer does not include the value of disabled controls in a postback to the server; secondly, an unchecked checkbox is not included in the post back either. So the way ASP.NET detects if a CheckBox has been unchecked, is assume that if checkbox is missing in the postback then it is unchecked, otherwise checked.

It also turned out that the customer was overriding the RenderChildren method for his purposes, and in that method he disabled some of the controls sent to IE after the controls have any chance to store their new state in view state. Then keeping the browser’s behavior in mind, ASP.NET believes the CheckBox was unchecked, and fired the onCheckedChange event.

In summary, upon a post back here, roughly the following operations/events take place in the ASP.NET framework:

  1. Initialization – Controls are initialized
  2. LoadViewState – Checkboxes’ are found to be present in the viewstate. Some of these are checked
  3. LoadPostbackData – IE does not post back any checkboxes that are either disabled or unchecked. Alas ASP.NET believe the checkboxes to be unchecked by the client IE user
  4. Load on controls are performed
  5. RaisePostBackEventonCheckChanged event is fired
  6. SaveViewState – When SaveViewState has been called, no changes to the controls performed afterwards are recorded
  7. Render – In this step you override RenderChildren and change the controls so their sent disabled to IE, but no ViewState information has been recorded. Thus from an IE perspective, they are not needed to be posted back

The solution to this one was: do not change a control’s state while overriding the RenderChildren event.

For further details, please see “Understanding ASP.NET View State“. Check out Fiddler for capturing and monitoring the HTTP traffic.

Cheers

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.