The Problem
ASP.NET validators and ValidationSummary controls are rendered as SPAN tags that are shown and hidden based on validation state. The properties of the validators are written normally via JavaScript calls similar to these:
<script type="text/javascript">
//<![CDATA[
var Page_ValidationSummaries = new Array(document.getElementById("vdsSiteLogin"));
var Page_Validators = new Array(document.getElementById("rfvEmail"), document.getElementById("revEmail"), document.getElementById("rfvName"));
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
var rfvEmail = document.all ? document.all["rfvEmail"] : document.getElementById("rfvEmail");
rfvEmail.controltovalidate = "txtEmail";
rfvEmail.errormessage = "Email Missing";
rfvEmail.validationGroup = "SiteLogin";
rfvEmail.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
rfvEmail.initialvalue = "";
var revEmail = document.all ? document.all["revEmail"] : document.getElementById("revEmail");
revEmail.controltovalidate = "txtEmail";
revEmail.errormessage = "Email is invalid";
revEmail.validationGroup = "SiteLogin";
revEmail.evaluationfunction = "RegularExpressionValidatorEvaluateIsValid";
revEmail.validationexpression = "\\w+([-+.\']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
var rfvName = document.all ? document.all["rfvName"] : document.getElementById("rfvName");
rfvName.controltovalidate = "txtEmail";
rfvName.errormessage = "Password is missing";
rfvName.validationGroup = "SiteLogin";
rfvName.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
rfvName.initialvalue = "";
var vdsSiteLogin = document.all ? document.all["vdsSiteLogin"] : document.getElementById("vdsSiteLogin");
vdsSiteLogin.validationGroup = "SiteLogin";
//]]>
</script>
Note that this is for ONLY 3 validators, 1 validation summary and in directly a page that doesn't use a master page, not in nested user control or such!
How about a page with over 30+ validators (yeah, those forms!!), and each with ClientID like "ctl00_cphBody_ct00_fvUserLogin_rfvEmail_" and such?
If you have ever wondered why those pages take so much time loading, this code block (multiplied per number of validators you have and their properties set) is one reason.
You cannot even take the JavaScipt in separate file that can be cached, because this is dynamically created as per the visible validation controls.
The Solution
The clear alternative to setting those properties via JavaScript long block with huge ClientIDs is to put the properties in the SPAN tags of the validation controls themselves.
The reason that AS.NET does not do this by default is that this is not XHTML 1.0 Transitional compliant, because the validator properties are not XHTML attributes of the SPAN tag.
ASP.NET tries to render XHTML 1.0 Transitional markup by default. But you can change that in your web.config file by adding one line under <system.web>:
<system.web>
<xhtmlConformance mode="Legacy"/>
This will make the properties render in the SPAN tags themselves, saving so much code in real life scenarios.
Personally I'd recommend: DO THIS IN EVERY WEBSITE YOU HAVE