Ensuring unique ID attribute for elements within ScriptControl

1.1k Views Asked by At

I'm creating a control based on ScriptControl, and I'm overriding the Render method like this:

protected override void Render(HtmlTextWriter writer)
{
    RenderBeginTag(writer);

    writer.RenderBeginTag(HtmlTextWriterTag.Div);
    writer.Write("This is a test.");
    writer.RenderEndTag();

    RenderEndTag(writer);
}

My question is, what if I want to assign the div an ID attribute and have it be unique on the page, even if there are mulitple instances of my control?

I've seen other people's code that does this:

writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_divTest");

That will prevent naming conflicts between instances of my control, but what if I've already created a div elsewhere on the page that coincidentally has the same ID?

I've also heard about implementing INamingContainer. Would that apply here? How could I use it?

UPDATE:

I've worked around this by overriding CreateChildControls and adding actual controls, as opposed to rendering HTML directly. In that case INamingContainer does its job. However, I'm still curious if there's a way to solve my original problem (unique IDs for directly rendered elements).

3

There are 3 best solutions below

5
On

INamingController is a marker interface. Implementing it will guarantee you unique ids for each instance of your control.

http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx

  public class MyScriptControl: ScriptControl, INamingContainer {

  }
0
On

You won't want to create instances of controls just to get unique Ids, there's useless overhead/complexity in that approach. The Control.ID property may not be unique, but the Control.ClientID property will be unique. Therefore

writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_divTest"); 

that attribute has to be unique unless you use the suffix "_divTest" twice in your custom control.

0
On

I am tried to realize your issue:

public class SC : ScriptControl
{
    protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
    {
        return null;
    }
        protected override IEnumerable<ScriptReference> GetScriptReferences()
        {
            return null;
        }
    }
    //... Page code
        protected void Page_PreRender(object sender, EventArgs e)
        {
            var sc = new SC();
            var sc1 = new SC();
            Page.Form.Controls.Add(sc);
            Page.Form.Controls.Add(sc1);
        }

But sc and sc1 have different ClientID. So it is not ASP.NET issue. Look over your realization. May be you generate ids for divs before adding ScriptControls to Page, or may be you try to create 2 divs in the scope of one ScriptControl, or may be you create ScriptConrol2 dynamicly on async-posback and it have the same id as ScriptControl1, that not added dynamicly on postback.