"ASP.NET without ClientID's" Project:
http://clientidless.codeplex.com/[
^]
Demo of rendering without ClientIDs:
http://show-demos.net/NoClientId/[
^]
ASP.NET 4 introduced new property for controls -
ClientIDMode
.
So developers (starting from ASP.NET 4) can control how
ClientID
attribute will be rendered.
Probably the main thing that was missed from view - in a lot of cases, developers don't use ClientID
at all on Client Side!
All these
Labels,
Panels,
HyperLinks and so on - we need their IDs only on server side to interact with them. It's really a rare situation when we access some label by id on client side.
Technically, only controls that may cause
PostBack
always need
ClientID
. For all other controls, it should be optional - but it's not. Currently ASP.NET renders ID for every control that has client side representation. As a result - each page has more heavy HTML output because of unused
ClientID
s.
So here is the trick now to turn off/remove ClientID
s:
The only thing we need is to have control over each control render.
ControlAdapter
is a good choice for this.
- Visit my project http://clientidless.codeplex.com and download sources.
- In your project, add ASP.NET specific folder "App_Browsers". (Right click on Web Project -> Add -> Add ASP.NET Folder -> App_Browsers)
- From downloaded sources, place
NoIdAdapter.browser
into App_Browsers folder and include it to project. Place NoIdAdapter.cs somewhere in your project and include it too.
That's it!
Now you can add attribute
noid="True"
to any control in a page and this control will have no id attribute on client side.
The usage is very simple, just check.
IMPORTANT: Controls that may do PostBacks (controls that implement interfaces
IPostBackDataHandler
and
IPostBackEventHandler
) will ignore
noid
attribute. This is expected because
ClientID
is very important for PostBack controls.
Example of rendering with IDs (Standard ASP.NET output):
<div id="repeater_ctl00_mainPanel" class="panel">
<div id="repeater_ctl00_childPanel">
<div id="repeater_ctl00_oneMorePanel">
<span id="repeater_ctl00_someLabel">Top Label</span><br />
<a id="repeater_ctl00_hyperLink" href="http://asp.net">
<img id="repeater_ctl00_someImage" src="/img/img.png" style="border-width:0px;" /><br />
<table id="repeater_ctl00_table" border="0">
<tr id="repeater_ctl00_headerRow">
<th id="repeater_ctl00_headerCell">
<span id="repeater_ctl00_label">Test</span>
</th>
</tr>
</table>
<a id="repeater_ctl00_button" href="javascript:__doPostBack('repeater$ctl00$button','')">LinkButton</a></a>
</div>
</div>
</div>
Example of rendering when
noid
is set to "
True
":
<div class="panel">
<div>
<div>
<span>Top Label</span><br />
<a href="http://asp.net">
<img src="/img/img.png" style="border-width:0px;" /><br />
<table border="0">
<tr>
<th>
<span>Test</span>
</th>
</tr>
</table>
<a id="repeater_ctl01_button" href="javascript:__doPostBack('repeater$ctl01$button','')">LinkButton</a>
</a>
</div>
</div>
</div>
As you can see,
repeater_ctl01_button
element still has
ClientID
. This is expected because it's a
LinkButton
- PostBack Control.
Source code:
NoIdAdapter.browser (please check latest version here
http://clientidless.codeplex.com/releases[
^] )
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.WebControl" adapterType="NoId.Adapter" />
<adapter controlType="System.Web.UI.HtmlControls.HtmlControl" adapterType="NoId.Adapter" />
</controlAdapters>
</browser>
</browsers>
NoIdAdapter.cs (please check latest version here
http://clientidless.codeplex.com/releases[
^])
using System.Web.UI;
using System.Web.UI.Adapters;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace NoId
{
public class Adapter : ControlAdapter
{
protected override void BeginRender(HtmlTextWriter writer)
{
if (Control is Table || !(Control is IPostBackDataHandler || Control is IPostBackEventHandler))
{
AttributeCollection attr = null;
if (Control is WebControl)
attr = ((WebControl)Control).Attributes;
else if (Control is HtmlControl)
attr = ((HtmlControl)Control).Attributes;
if (attr != null)
{
string noId = attr["noid"];
if (noId == "true" || noId == "True")
Control.ID = null;
if (!string.IsNullOrEmpty(noId))
attr.Remove("noid");
}
}
base.BeginRender(writer);
}
}
}