If you are automating the setup of your Validators, such as in a Page Load event, in conjunction with the Login control, you may find the Page Validators collection is unexpectedly empty.
This is because the Framework is missing a call to EnsureChildControls (a protected method of the derived Control class).
If you happen to call FindControl on the Login control or access the Login's control, Controls collection, this invokes EnsureChildControls, creating the controls collection and therefore the Page Validators collection as well.
If you only want to use the Page Validators collection and have no need to call FindControl or access the Controls collection, you could use reflection to invoke the EnsureChildControls method (Login1 is the instance of the Login control, replace with ID of your Login control):
using System.Reflection;
// ...
// Manually call EnsureChildControls (not called by Framework), so Page.Validators collection is setup
typeof(Control).InvokeMember("EnsureChildControls", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, Login1, null);
If you don't want to use reflection for some reason, you could make a dummy call to FindControl:
// Make dummy call to FindControl, so Validators collection is setup (invokes protected method EnsureChildControls(), not called by Framework)
Login1.FindControl("");
Background:
I had a routine that iterated through the page validators to set common properties and because of the above, it wasn't working. I switched to a recursive routine to iterate through the control hierarchy, but this still didn't work because I was using the HasControls method to see whether a control had any children. When I switched to the statement "if (control.Controls.Count >= 1)" it miraculously started working. This is because, as stated above, accessing the Controls property called EnsureChildControls (specifically the CompositeControl get implementation). I have now reverted to my original code...