Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Overriding ClientID and UniqueID on ASP.NET controls


:P
On this page:

So I posted the updated wwHoverPanel control yesterday and while it addressed some of the core issues, it still isn't working in all situations due to the naming issues of the ASP.NET containership naming schemes. Well, ASP.NET is doing nothing unpredictable really, but my goal for the control was that it should be easy to reference and access from within script code.

 

So when the control is hosted in a MasterPage and you're doing a JSON page callback I don't want the user to have to use a cryptic name like:

 

ctl100_Content_LookupPanel.Helloworld('Rick',Helloworld_Callback);

 

or

 

document.getElementById('ctl100_Content_LookupPanel');

 

To do this the user either needs to type the ugly name above or:

 

<%= LookupPanel.ClientID %>.Helloworld('Rick',Helloworld_Callback);

 

So anywhere the panel is referenced then would require code like this which is – well, ugly as shit. It also makes the control handling a lot more difficult, because in some cases the control would have to generate the base ID (LookupPanel) or in other cases generate the ClientID into the code.

 

To end user the experience is confusing.

 

Given that this is a 'worker' control, not something that will be stuck into containers and iterated over it seems much more reasonable to use simple names directly:

 

LookupPanel.Helloworld('Rick',Helloworld_Callback);

 

and

 

document.getElementById('LookupPanel');

 

So, today I realized an obvious solution which is to simply override ClientID and UniqueID in the control class:

 

/// <summary>

/// Override to force simple IDs all around

/// </summary>

public override string UniqueID

{

    get

    {

        return this.ID;

    }

}

/// <summary>

/// Override to force simple IDs all around

/// </summary>

public override string ClientID

{

    get

    {

        return this.ID;

    }

}

 

This complete overrides the extended naming functionality that ASP.NET provides and results in the control names being rendered into the output as a simple ID names that don’t reflect the control hierarchy.

 

So now the code automatically generates the simple ID all the time both for client and server side code and users can talk to this control with its simple name in script code.

 

For this particular control which essentially isn't bound to the control tree hierarchy this is just fine. The control either fills the panel with data from an AJAX callback and displays it inplace or moved up to the mouse cursor, or it acts essentially as non-visual control – when allowing JSON Pagecallbacks.

 

Now, there's a caveat of course: Due to this overriding the page author now has to ensure that the name of the control is unique on the page. Since this control is likely to be only dropped once maybe twice (once for panel operation and once for callback operation) this is not really problem, but it is unconventional. I can live with that.

 

Can anybody see where this would cause problems beyond possible naming conflicts?

 


The Voices of Reason


 

Wilco Bauwer
February 24, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

You have to be careful with postbacks. The Page normally uses the ClientID (the one posted by the client) to find the control instance. In a nutshell it just splits the ClientID, so myContainer_myTextBox would result 2 strings, myContainer and myTextBox. It will then try to find 'myContainer' as a top-level control. If it can find it, it will try to find 'myTextBox' within the found 'myContainer' control.

In your case, the ID does no longer contain information about the control hierarchy. That's why the Page will be unable to call the control's LoadPostData/RaiseChangedEvent methods. As a result, your control may no longer work if it implements IPostBackDataHandler.

I've implemented a generic control, IDOverride (http://www.wilcob.com/Wilco/News/AspNetIDOverride.aspx), which should both let you do what you want to do, and take care of the problem I described.

Rick Strahl
February 24, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

Thanks Wilco. In this case it's not a problem because the control isn't a PostBack style control. The only postbacks that occur are for Method Callbacks to the page, which are handled entirely internally with custom POST vars passed back.

Like that idea of the override control - slick idea. That might come in handy in other places. In this case though the control has to manage the id on its own.

Stig
March 07, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

Hi Rick, I was thinking about this problem the other day and could not figure out a solution to this sh... But you did, thank you :-)
Stig

Ola
March 11, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

This is just the information I wanted. I have been trying to give the body tag in an ASP.NET master page my own id. I don't have to worry about conflicts since there will be just one body on the page.

Thank you guys.

Halit Develioglu
June 28, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

Spending my all day trying to solve this strange problem and finally reaching the solution. Now I can sleep in peace.

Thank you Rick

Halit Develioglu
Turkey


Keywords used : asp.net custom control unable to find uniqueid

yugu
August 31, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

Rick,

I have been battling with the id issue for quite some time. Your idea of overriding the control class' uniqueID and clientID is great. But where do I override them?

thanks!

yugu

Web Forms
September 27, 2006

# ASP.NET Forums - ClientId of a user control too long


Ángel
October 04, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

Uau!!!

I've been fighting for 5 hours trying to figure out a way to preserve the ID of my controls during an Ajax callback in which some of the controls may have been deleted.

Thanks!!!

Greetings from Spain

Custom Server Controls
October 19, 2006

# ASP.NET Forums - How to force...


Moskie
October 29, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

Hello, I'm using this method to force the IDs to be what I want, but I've encountered another problem that I think might a be a result of using this method.

I've created a class that inherits from HtmlGenericControl. It overrides UniqueID ans ClientID so that they both return this.ID. It also has contructors in the class that call the base class' constructors... and that's all that I have in the class.

But now I'm getting an error when I try to view the Trace page of a page that uses objects of this type. The error is a Null Reference Exception that occurs in System.Web.Handlers.TraceHandler.CreateControlTable(DataTable datatable) +2442. I'm not 100% sure that using my custom class is causing the problem, but that's my suspicion.

Can someone confirm (or refute) this for me? I'm thinking there's something else I have to have in my class, but I'm not sure what that is. Any help is appreciated!

10x!!!!!!!!! Finally!
November 23, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

I spent A WHOLE DAY !!!

garima
December 21, 2006

# re: Overriding ClientID and UniqueID on ASP.NET controls

is there any other way to get the master pages controls id at the client side other than this using this ajax...???

Sanket
January 08, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

I am facing strange problem.... i have custom control on my aspx page.... problem is that on one server client id is like AAAAA_myTab.
While on other server it is like AAAA_myTab$.

Can anyone have any idea ?

mcm
February 11, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

Thanks, exactly what i was looking for. (dual image swapping on a user control)!
woot woot!
mcm

moody
February 14, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

I think that does not apply to ContentPlaceHolders of masterpages. I cant find a way to convert "contentplaceholder_x' ids into 'x'.

# Technical blog: ASP.NET, C#, VB.NET, ADO.NET: oktober 2006


Michael
April 22, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

The solution on the top of the page works great for IDs, but what about control(element) names. For example i would need the name of the control(element) of which value is posted to another site to remain the same.
<input id="ProductID" type="text" runat="server" name="ProductID" />
.
Are custom controls the only solution to this problem?

Rick Strahl
April 22, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

Overriding the name would require changing the Name attribute in the Attributes collection. You can certainly do that but why on earth would you do that?

ASP.NET Forums
May 25, 2007

# How to force... - ASP.NET Forums


ASP.NET Forums
June 20, 2007

# ClientId of a user control too long - ASP.NET Forums


D'Arcy from Winnipeg
July 12, 2007

# Overriding Unique ID's in Web Controls


Steve
July 18, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

I have been debating this for some time, semantically from a designer perspective its desireable to have unique id's without the hierarchy strings attached that are relative to the containers, however, if you use the Page.ClientScript functionality, the workaround is fairly simple. This might not directly bolt-on to current AJAX designer based implementation, but what's wrong with writing the required JavaScript per control by hand in the first place?

I am in total agreement that Microsoft could have improved the current model before releasing it, but I have long adjusted to the fact if you want to do something (especially using Microsoft), the only way to get it to work and production worthy is to live by the standards bodies such as Microsoft set out. If you try and bend the system to satisfy your own wishes, it breaks. Keeping the UniqueID and ClientID's is certainly the only way to sleep at night, unless of course, your willing to write your own framework, which is something that is really not that difficult!

Good luck to all who choose otherwise! I have been their, had solutions fall over in places are dread to recall.

S

Rick Strahl
July 18, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

Steve - I would tag this as a special use scenario not something you do wholesale for all controls you create. But there are certain controls that are likely going to be single instances on a page and removing the funky ClientId formatting that Microsoft uses can greatly simplify access to these components.

I built this originally for a few AJAX controls which are sort of global managers on a page. In that scenario you're not going to have name-duplication unless a custom control uses the same component AND chooses the same name (possible but unlikely - custom controls at the very least might obfuscate names internally or even be Ok with full client ID names).

It's a special case scenario and I agree - you'll want to be super careful with this sort of 'swimming against the current'.

Steve
July 24, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

Rick, for some reason the later part of my post is missing, however, my closing point was more or less the same as you just concluded, but I did go on to mention my worries for AJAX and the support of JavaScript and XML for other readers other than 'so called' standard pc based web browser, by this I am really referring to TV's, Mobile devices etc, so far and to date, I personally have found the lack of support so low that we have ditched AJAX and most of Microsoft's ASP.NET framework and reverted to standard HTTP post. Why? because we needed to implement something that worked! I would love to implement AJAX in a commercial environment, yet still humbled by the fact that even with ECMA and little else other than an XML Dom, basic functionality is still near impossible to achieve, forgive my pesimistic view here, but I would love someone to convince me that AJAX is worthy of use in production/commerical environments. I am losing the faith I think, been working too long in this industry and still it feels as though the concept of Standards based design is miles away. Quick somebody throw me a line...

Gus
September 20, 2007

# re: Overriding ClientID and UniqueID on ASP.NET controls

Hello, is there someway to override de clientID of contentplaceholder???
in my website the ID looks like this:

..."TextBox Id="contentplaceholder_visHome"...
.


this is inside a content page...
using your method on master works fine... but what can i do to override the IDs inside de contentplaceholder???

tks!!!

kazim mehdi
February 20, 2008

# re: Overriding ClientID and UniqueID on ASP.NET controls

Thanks for this great article.


kazim

kazim mehdi
February 20, 2008

# re: Overriding ClientID and UniqueID on ASP.NET controls

what i think is best suited is override just those controls whose id is used on client side e.g in passing data through post .


kazim

Matteo
March 27, 2008

# re: Overriding ClientID and UniqueID on ASP.NET controls

Great post, thanks

I've used your idea to eliminate the unused IDs of Label controls inside a GridView.
I' ve a lot of controls nested inside other controls and the asp.net framework generates very long clientId for every server control.

I've created a SimpleLabel custom control derived from Label and replaced it inside my GridView...
Then I've overriden the ClientID returning null.
The result is that every label is rendered as a simple SPAN element without the ID.
With 20 lines of code I've saved a lot of space in my page.

bye,
Matteo

Jinn Nguyen
October 02, 2008

# re: WOOOOOTTTT

Works like a charm.

I have a nested dynamic controls which are generated depend on user's action in one page. (no another choice)

And sometimes the button inside the control is not fired after the 1st post back. Why? Because the stupid Client ID keeps changing and Click event is not registered properly no matter how much you have re-initiated them.

It is not advisable to use everywhere, but this can be a workaround for a lot of CONTROL like in mycase.

THANKSSSSSS

JINN

anonymous
December 26, 2008

# re: Overriding ClientID and UniqueID on ASP.NET controls

This solution seems a little hacky, although it works in certain situations. Be careful about changing IDs this way for ASP.NET Controls that implement IPostBackDataHandler interface. On postback, to raise events on these controls ASP.NET first needs to know that it are indeed these controls that the data is being posted back for. To do that it looks at the HTML name/ids to find the corresponding control object on the server. The ids themselves are created such that they contain the hierarchy information for controls that lets ASP.NET point to a specific control.

Alex Czarto
January 02, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

Another post on a similar topic but using a slightly different strategy (by overriding the NamingContainer property):
http://www.gljakal.com/blog/2007/09/12/getting-rid-of-the-naming-container-in-aspnet-20/

Mike Borozdin
February 26, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

Hello Rick,

I came up with another workaround. We can give to each control we want to access with JavaScript a unique CSS class name by setting a value in the CssClass attribute and then we can access an appropriate control with the jQuery selection:

$("tagName.className")

I explained this method in blog post: http://www.mikeborozdin.com/post/CSS-Class-Names-Instead-of-ASPNET-Client-IDs.aspx#comment

Frank Sleeper
February 27, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

Check out http://www.mostlylucid.net/archive/2008/11/03/way-too-much-information-on-control-ids-and-asp.net-4.0.aspx

This explains the .NET support approach for controlling the generated ClientID. Though - I need to dig deeper as I know there is a hook into page generation where more advanced logic could be injected when needed.

Back to the point, the article covers a few concepts. Specifically, that there are options that can be set at the application, page level, or "context" level.

Best to just read the article versus me cut-and-pasting too much here :)

Cam Woods
March 03, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

This article was helpful in making sure my client-side controls were named as expected so that my javascript didn't break. However, as mentioned, it breaks postbacks since the resulting client-side id's don't match the server-side control hierarchy.

I eventually got all that working by deriving my own MasterPage and ContentPlaceHolder controls and by juggling the control hierarchy during the page PreInit. I ended up writing about it and providing the source code necessary (C#).

Hope this helps. Feel free to copy the code:

http://www.netquarry.com/index.php/2009/03/master-pages-ajax-and-javascript-10292/

Glenn
March 12, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

This solution worked nicely for using a radio button inside a grid. I inherited from HtmlInputRadioButton and overrode those two properties so that my radio buttons would work together inside my grid.

Maarten
April 24, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

Every time I have something like, damn why does asp work that crappy, I always end up on your website.

I just want to force that my elements have the name I give them, asp doesnt like customized scripts, crappy framework.

Thnx man

Rhett
June 23, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

I used this method a while back to implement content areas within html pages that would be accessible by inserting a fragment identifier in URLs. That works no problem. My issue with this method however is that it breaks the trace for all pages that use this control. When I select the trace file I get a "Object reference not set to an instance of an object" error coming from System.Web.Handlers.TraceHandler.CreateControlTable(DataTable datatable), so I cannot access trace debugging info on the page.

Aaron Clausen
November 02, 2009

# re: Overriding ClientID and UniqueID on ASP.NET controls

More tragic hacks purely to get around the shortfalls of ASP.Net web forms.

Just forget all this and go straight to ASP.Net MVC :) Web forms=FAIL.

Sky
June 24, 2010

# re: Overriding ClientID and UniqueID on ASP.NET controls

If you are trying to find the IDs of such controls on the client side then you can use:

document.getElementById('<%= ControlID.ClientID %>')

Where ControlId is the id that you gave to your control at design time

and ClientID is the syntax (use it as it is)

So for example if you have a text box like this:

<asp:TextBox runat="server" id="inpErr" ></asp:TextBox>

then you will write something like this:

document.getElementById('<%= inpErr.ClientID %>')

to find out the actual id of your control.

Good luck,
Sky

Exception Duck
July 08, 2010

# re: Overriding ClientID and UniqueID on ASP.NET controls


Chisha
May 22, 2013

# re: Overriding ClientID and UniqueID on ASP.NET controls

Thank you very much I had a set of radio buttons that were being added
server side and also java script side which both needed to use the same
name otherwise the radio buttons will not see each other.

but I created a server control based on this article and it worked.

I didnt want to use JQuery to rename because thats not efficient
hence your solution is very good for the long run
and the page does not use post back so your solution works best.

Thanks

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024