ASP.NET long Name attribute - Why is there no ClientNameMode - asp.net

In ASP.NET much has been made about the ClientIdMode property that gives developers greater control over the a control's ID attribute as it appears in the HTML.
However little attention appears to have be paid to the way the controls render their Name attribute. It appears to be a simple concatenation of the control's ID and its hierarchy of naming containers.
Given a sufficiently complex web page these names get very long. They not only make the HTML payload big (and ugly) but are also posted back to the server on every postback. (Also, they make their way into the Control State of some third party control suites. )
Why isn't there a ClientNameMode property - or similar? Surely it is as important as the Id attribute? Is it possible to override some method that generates / rehydrates the Name attribute so that we can man handle it to maybe match the Id? (made shorter by the ClientIdMode)
An example of a name of a control on a page that I am working on is
USoWAR1_tabContainer_UDetailsTabContainer_tabContainer_UDetailsTab_UDetails1_UDueDateAndNotifications1_decDetail_DataEntryRow1_datDueDate_DateTimePicker_calendar_AD

As far as I know the only way to alter this functionality is to extend controls into your own and override UniqueID property (e.g. by returning Server-side ID).

I had this same issue, and had to use JS to set the attr after loading.
$('#idofdomobjiwanttoname').attr("name", "whatIWantToNameIt");

Related

Custom control names (not ID) in ASP.NET to use with JQ.serialize

I am developing a website using mainly AJAX for saving and retrieving data in order to avoid postbacks (or at least full postbacks).
I "prepare" the page in codebehind, and on client I use JQ and Javascript.
When I want to save data I serialize the elements in a container (using JQ) and then AJAX post to send data to the WebMethod.
This is working well but I have to deal with long name elements ("ctl00$MainContent$grdEmployees$ctl03$ddlRole").
Sometimes is difficult to retrive data from the NameValueColletion as the same WebMethod can be called from different pages, so the "name" of the element is not the same as the control may be nested in other container.
Is there a way to set custom names for ASP.NET controls to avoid this issue?
Or other way to achieve this behavior?
Best regards.
Have you tried to use ClientIDMode="Static" which is found in .NET 4.5.
When a page is render the ids all change as you have noted. However, you set the ClientIDMode to static it will render with the ID that you have put for the control itself. That way you can work with the ID of the control instead of the generated id. If you would like to know more here is a like to the MSDNA about ClientIDMode
http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode(v=vs.110).aspx

Using the ASP.NET ClientServerManager method or property to get name of control

Does the ASP.NET ClientServerManager provide some method or property to return the name of an ASP.NET control in the generated html page that could be used to write the javascript (using RegisterClientScriptBlock) in the code-behind? The actual generated control names can be quite long and unknown (I am also using master pages). I would like a generic way to write the javascript text and have the actual names of the controls be added to the javascript string. I would expect some method that I pass in the name of the control and it returns the actual html control name. I have searched in the documentation of the ClientServerManager and could not find anything.
Control.ClientID is rendered as html tag ID, so you can use that property.
If you are worried about control names, check out ClientIdMode where you can specify this and make it much simpler.
http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode.aspx
Would this help your issue?

How does ASP.NET Webforms decide HTML name of a control?

In ASP.NET web forms when a control is rendered on the page, the ID of each field is modified with the ctrl01 as needed to ensure collisions don't happen (aka myField becomes ctrl01$myField or whatnot).
I was wondering where one might find details on HOW the algorithm itself works, or where it might be I can find it. I am assuming the INamingContainer has something to do with this-- but alas I cannot find the part which actually decides the rendered field name.
Any help would be awesome!
You are probably looking for this msdn article.
It's based on the hierarchical layout of the webpage. But you can control this with the ClientId property.
So a textbox in a usercontrol will be named ctrl01#textboxname (Like you said in your post)
It concatenates it's own name with your original id.
In ASP.NET 4 you can suppress this concatenation and keep your own id in three different ways:
Each server control has an attribute called clientIdMode which you can set to Static
You can also set clientIdMode in the page directive which will affect all controls on the page.
Or you can set it in the web.config to affect all controls in all pages. (Unless the page or control is set to a different clientIdMode
Note: If you are using AJAX Control Toolkit you will need to set those controls that are part of the toolkit to a clientIdMode of Predictive
Apart from the other answers, if you are using ASP .NET 4, you have much more control over it.
Take a look # these web pages
http://www.west-wind.com/weblog/posts/54760.aspx
http://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview.aspx

asp.net 4.0 webforms - how to keep ContentPlaceHolder1_ out of client id's in a simple way?

I'm attempting to introduce master pages to an existing webforms site that's avoided using them because of client id mangling in the past (and me not wanting to deal with the mangling and doing <% foo.ClientID %> everywhere :)
GOAL: use 'static' id values (whatever is in the server control's id attribute) except for data-bound / repeating controls which would break for those cases and therefore need suffixes or whatever to differentiate (basically, Predictable)
Now that the site migrated to ASP.NET 4.0, I first attempted to use ClientIDMode of Static (in the web.config) but that broke too many places doing repeating controls (checkboxes inside gridviews, for instance) since they all resulted with the same id.
So, I then tried Predictable (again, just in the web.config) so that the repeating controls wouldn't have conflicting id's, and it works well except that the master page content placeholder (which is indeed a naming container) is still reflecting in the resulting client id's (for instance, ContentPlaceHolder1_someCheckbox).
Certainly I could leave the web.config setting as static and then go through all the databound/repeating controls switch them to Predictable, but I'm hoping there's some easier/simpler way to get that effect without having to scatter ClientIDMode attributes in those N number of places (or extend all those databound controls with my own usercontrol that just sets clientidmode, or whatever).
I even thought of leaving web.config set to static and doing a master or basepage handler (preinit? not sure if that would work or not) that would go walk Controls with OfType<INamingContainer>() (might be a better choice on the type, but that seems like a good starting choice looking at repeater and gridview) and then set those to Predictable so I'd get static for all my 'normal' things outside of repeating controls but not have to deal with static inside things like gridview/repeater/etc.
I don't see any way to mark the content placeholder such that it 'opts out' of being included in child id's - setting the ID of the placeholder to empty/blank doesn't work as it's a required attribute :)
At that point I figured there was a better/simpler way that I was missing and decided to ask on SO :)
Edit: I thought about changing all my 'fetch by id' jquery calls from $('#foo') to fetch_by_id('foo') and then having that function return the 'right one' by checking $('#foo').length and then $('#ContentPlaceHolder1_foo').length (and maybe other patterns) or even just have it return $('#foo, #ContentPlaceHolder1_foo') (again, potentially other patterns) but changing all the places I fetch elements by id seemed pretty ugly too, and I'd like to avoid that abstraction layer if possible to do so easily :)
Edit2: WRT using jQuery selector of id$='foo':
my worry doing such a thing (although it may be more imagined than real) is when one of the id's in a page ends with another. For instance, if a page has elements with id's of 'foo' and 'barfoo' then id$='foo' will accidentally include the 'barfoo' as well. Certainly there are plenty of methods for preventing that (like suffixing with the element type, so fooCheckbox and barfooButton or whatever) but I didn't want to have to scan the existing source and/or enforce a new rule for naming.
Since not all of the controls are server controls, I can't $='_foo' either since a normal div id="foo" won't be found (and I'd rather avoid runat="server" just to mangle the name :)
another thing I considered was making a unique css class name per element and selecting on that instead (since class obviously doesn't get mangled) but it's very hacky to do so and certainly muddies things up when doing the 'real' CSS work :)
ClientIDMode = UI.ClientIDMode.Static
You have to set this in the "constructor".
I honestly don't know if there is an easy way of doing it, but considering you are using jQuery what I have done in the past is, I used the attribute ends with the selector method.
Since .Net appends your "static" id to the end of it's generated id, you can get that with the jquery selector $("input[id$='yourstaticid']").
I know this is not THE solution that you are looking for but it would make your 'fetch_by_id' simpler.
Hope it helps or gives you an idea at least.

.Net Changes the element IDs

.Net is kindly changing the element ids on my pages by appending a ct100_ to them. As much as I appreciate microsoft trying to help me keep from duplicating ids on my site, I think I can manage it on my own. Can anyone tell me how to prevent this?
Thanks in advance.
That's just how aspnet works. Controls provide the clientid method for you to use in your code behind for this reason.
If you want to refer to objects from js, you can either inject the clientid or use classes or other attributes.
Edit: Note that this only applies to the ASP.NET controls. If you use the HTML controls, the given IDs are preserved. You can access them in your code behind by adding the runat=server attribute to them, too. Obviously these controls break the webforms model with viewstate, etc. but they do give you your desired functionality.
Of course it's been a while since I worried about it so I could be wrong...(please comment or edit if I am!).
You cannot prevent this in the current version of ASP.NET - the next version will allow you to do this. Perhaps ASP.NET MVC is a good choice for you?
Any control which has the INamingContainer interface on it will get the control heirarchy appended to it to allow for multiple controls to be on the page without conflicting. You should be using the ClientID property of the control if you wish to know what the id of the element will be on the client.
You will need to:
override regular controls' behavior to decouple the Control.UniqueID property from the Control.ID property
override naming container controls to allow us to control how ID generation is done and how to find a control
References:
http://nunogomes.net/post/2008/06/02/ASPNET-Controls-Improving-automatic-ID-generation-Architectural-Changes-(-Part-3).aspx
http://weblogs.asp.net/nunogomes/archive/2008/06/04/asp-net-controls-improving-automatic-id-generation-architectural-changes-part-3.aspx
http://forums.asp.net/t/1394822.aspx
to not use anything on the server side.
This is an inherent aspect of the ASP.NET system, and there is no way to use .NET Server controls and not have the prefixes appended.
To access the client-side name, you can use the myControl.ClientID property.

Resources