should every element with runat=server have an id attribute? - asp.net

I have inherited an asp.net website to maintain
when looking at the aspx page, almost every element with runat=server don't have id attribute defined.
should I go through every element and add one?

Unless the control is inside a repeating control it should have a unique ID attribute assigned to it. Here is some MSDN documentation on how to add server controls to an ASPX page.

You only need to give them ids if you're going to reference them in your code. If you're not referencing them at all you might wonder why they are .net controls and not just html elements.

ASP will assign an unique ID if you don't. Sometimes I don't bother when I won't be manipulating it.

Speaking specifically to your situation of having inherited an app, it's not a pressing issue. ASP.NET will automatically generate IDs for them at runtime.
Generally, aiming to replace those controls with HTML elements (as someone else mentioned) is a good idea. Do be careful though. Just because an element doesn't have an ID doesn't mean it's not being referenced on the server side at runtime.

You don't need to set IDs to the controls you don't reference. ASP.NET will do it for you. That's it.
This does NOT automatically mean, they can be replaced with HTML controls. Having a control with runat="server" without having an ID set is perfectly reasonable.
e.g.:
<asp:ListView runat="server" DataSourceID="someDataSource">

Related

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

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");

How to make ASP.NET server controls get the shortest IDs?

I am using ASP.NET 4.0 WebForms. I am also using master pages which inherit from other master pages. I have controls inside panels. Basically there are multilevel containers. This is causing elements to have HUGE ID's. I am seeing ID's about 300 bytes long!
When there are hundreds of elements in a page, these ID's increase the page's size dramatically. I have a GridView with binding controls.
What is the best way to have each server control have the shortest ID possible? Is there a way to have each element not be dependent on its container (other than ClientIDMode="static") ID even if but still be unique in the page? Last, does ASP.NET MVC alleviate this issue?
I would suggest changing the ClientIdMode to either Predictable or Static in order to see if that produces shorter ID's.
Further to that this CodeProject article appears to achieve what you need.
MVC absolutely alleviate this issue because there is no server side rendering of html code in the same manner. All of your html is directly in your views so you have full control over every item. You also run the risk (in the case of a page that has hundreds of inputs) of colliding inputs.
One way you can help shorten all the html produced in WebForms is to remove anything that is not absolutely necessary to be a webusercontrol. For instance, most labels are static. They can replaced normally with standard text or items that don't include the runat="server" attribute. This will prevent ids from being generated in the first place. Another way to reduce the amount of junk that gets generated is to remove as many controls as you can from the ViewState. This will prevent them from loading their state data and keep the ViewState shorter.
ClientIDMode is an inheritable property so you can set it in the web.config (global), web.config (local) or page level. You could also use it individually. Your question specifically eliminates this, but it would probably be the best option with the most flexibility without rewriting what you already have. If rewriting is not an issue, I'd recommend using MVC.
I think ClientIDMode=static is in one of the way. YOu can set this in your web.conf also. And in Asp.Net mvc, you have the full conrol over html (especially in Razor). There is no such thinks like webforms. You have control over assigning ids to html tags. Infact Asp.Net mvc is answer to all other frameworks.
Last, does ASP.NET MVC alleviate this issue?
Yes.
There is no ViewState in MVC and you are not running any controls on the server.
You are not using any server controls which generate tons of hard to read HTML.
You have complete control over ClientID's in MVC.
Click
The above markup will always have the id of myID unless I change it myself.

How does ClientIDMode work?

I'm preparing to do an .NET exam and I came across this question. I have been breaking my head over this but I can't figure it out :s I tried all of this but didn't come up with a clear answer...
You are implementing an ASP.NET application that uses data-bound GridView controls in multiple pages. You add JavaScript code to periodically update specific types of data items in these GridView controls. You need to ensure that the JavaScript code can locate the HTML elements created for each row in these GridView controls, without needing to be changed if the controls are moved from one page to another. What should you do?
A. Replace the GridView control with a ListView control.
B. Set the ClientIDMode attribute to Predictable in the web.config file.
C. Set the ClientIDRowSuffix attribute of each unique GridView control to a different value.
D. Set the # OutputCache directives VaryByControl attribute to the ID of the GridView control."
This is what I came up with:
A. Since the structure of the GridView and the ListView is similar and
since they generate the same sort of IDs, I scratched this one.
B. I tested this, but it doesn't seem to affect the IDs :s I think I
would have to apply more settings than just this one to get some
effect.
C. This makes me wonder about what the question really says, this
makes all rows unique. But is that what is supposed to happen, since
you're not supposed to change code?
D. This is for caching, so has nothing to do with the question.
Can someone clear this out for me? Any ideas?
The question tells that ther can be data-bound GridView controls in multiple pages and also, if one gridview control is removed from one page to another page then it should work without any conflict with the already present gridview control.
so for th at we need to set GridView.ClientIDRowSuffix Property. So the answer is C.
Check this MSDN link.

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

.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