Question

I have custom server control, which contains three textboxes. I need to validate its content using ASP.NET field validators.

I set 'ControlToValidate' property of RequiredFieldValidator to the ID property of my textbox, but it seems that the validator is unable to find this textbox. Here is simplified code of what I'm trying to do (fields and properties that are not currently in use are omitted):

[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl runat=server></{0}:ServerControl>")]
public class CommentServerControl : WebControl, IPostBackDataHandler
{
    private TextBox _textBoxName;
    private RequiredFieldValidator _requiredName;

    protected override void OnInit(EventArgs e)
    {
        var idName = "Name-" + UniqueID;
        _textBoxName = new TextBox();
        _textBoxName.ID = idName;
        _textBoxName.ClientIDMode = System.Web.UI.ClientIDMode.Static;
        _textBoxName.ValidationGroup = ValidationGroup; // is set up via mark up
        Controls.Add(_textBoxName);
        _requiredName = new RequiredFieldValidator();
        _requiredName.ID = "RequiredName-" + UniqueID;
        _requiredName.ValidationGroup = ValidationGroup;
        _requiredName.ErrorMessage = RequiredMessage; // is set up via mark up
        _requiredName.ControlToValidate = _textBoxName.ID;
        Controls.Add(_requiredName);
    }

    public string ValidationGroup
    {
        get
        {
            var s = (string)ViewState["ValidationGroup"];
            return (s ?? string.Empty);
        }
        set
        {
            ViewState["ValidationGroup"] = value;
        }
    }

    public string RequiredMessage
    {
        get
        {
            var s = (string)ViewState["RequiredMessage"];
            return (s ?? string.Empty);
        }
        set
        {
            ViewState["RequiredMessage"] = value;
        }
    }
}

Running this code, I receive an error 'Unable to find control id 'Name-ctl00$MainContent$ctl00' referenced by the 'ControlToValidate' property of 'RequiredName'.'

I have read that this might occur because controls have different NamingContainer, but in this case references to NamingContainer are the same. However, FindControl(string id) method can't find my textbox control in OnInit method. What am I doing wrong? Thanks in advance.

Note: using UniqueID for creation of ID is used to prevent collisions in case of multiple use of my control.

Was it helpful?

Solution 2

I've found out where is the problem. I don't know yet why, but ID property of control must not contain '$' character. In my case, UniqueID property returned string like 'ctl00$MainContent$ctl00', so complete ID of control was 'Name-ctl00$MainContent$ctl00'. Replacing '$' with other symbol (to preserve uniqueness) solves the problem. By the way, FindControl method also began to work.

_textBoxName.ID = "Name_" + UniqueID.Replace('$', '_')

Also note, that symbol '-' as validator's ID will cause syntax error in JS (as ASP.NET will try to create JS objects with the same name), so it is not recommended to use it either.

OTHER TIPS

On_Init is too early as the controls won't have been created at that point.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top