I just spent some quality time with Firefox and Firebug trying to figure out why my client-side validators weren't preventing a postback when invalid data was entered. The symptoms were puzzling: when I entered invalid data and then attempted to submit the form, the validators would appear briefly, but then the page would post anyway!
A little debugging revealed that the button I was clicking called the JavaScript function WebForm_DoPostBackWithOptions, which called Page_ClientValidate, which called ValidationSummaryOnSubmit. This function looped through a list of validation summaries named Page_ValidationSummaries and then performed operations on each list element, which naturally meant accessing its properties.
ValidationSummaryOnSubmit doesn't test each summary in the list to ensure that the summary is not null before attempting to access its properties, so if a null reference finds its way into this list, an error occurs, which causes the entire call chain to terminate abnormally, in this case resulting in a failure to prevent the form from posting.
A little more debugging followed, and I located where the Page_ValidationSummaries list is initialized, and found which reference was returning a null value. It was a validation summary in the footer of a DataGrid, and the DataGrid's ShowFooter property was false. This of course meant that all of the controls within the footer were never rendered to the client, but the code that generated the list of summaries was including the reference anyway.
The solution to the problem was clearly to find a way to get the generated script to exclude the summary when the footer wasn't visible. I tinkered with a few alternatives, ultimately settling on this one: set the summary's Enabled property to be databound to the expression:
Enabled='<%# DataBinder.Eval( Container.NamingContainer, "ShowFooter" ) %>'
Within templated controls such as a DataGrid, Container refers to the DataGridItem of the current row. DataGrids are naming containers for DataGridItems, so accessing Container.NamingContainer gives a reference to the DataGrid. Eval then uses reflection to find the ShowFooter property of the grid and assign it to the Enabled property of the contained ValidationSummary. My testing showed that with this expression, the summary no longer appeared in the Page_ValidationSummaries initialization list when the footer was hidden, and client-side validation prevented postbacks again. Problem solved!