Я ударился головой об этом в течение некоторого времени. В конце концов я сдался и сделал свой собственный контроль веб-формы, который позволил мне установить идентификатор, как я хотел. Вот копия / вставка моего кода:
public abstract class BetterHTMLControl : WebControl {
private readonly HtmlTextWriterTag _tag;
public BetterHTMLControl(HtmlTextWriterTag tag) {
_tag = tag;
}
/**
* ASP.NET code uses the ID as the control reference variable name. It then changes
* the name to a generated (and ugly) field when rendering the control.
*/
public override String ID {
get {
/*
* In the end, there can be only one "id" attribute for the element.
* ID is set by ASP.NET and may possibly be set in the code afterwards.
* HtmlID is typically set in the ASP.NET code, and may be set before or
* after ID is set.
*
* If HtmlID is explicitly set, then we want its value to be used for the
* rendered "id" attribute and all other callers of "ID". Thus, check HtmlID
* for null; if it's not null, return it instead.
*/
String statedID;
if (_htmlID == null) {
statedID = base.ID;
}
else {
statedID = HtmlID;
}
return statedID;
}
set {
base.ID = value;
}
}
/**
* Helper property for within ASP.NET code (where ID is reserved for the reference
* name). If HtmlID is set, it takes precedence over the regular ID. The ID
* property is then used as the "id" attribute for the rendered element.
*/
private String _htmlID;
public String HtmlID {
get {
return _htmlID;
}
set {
_htmlID = value;
}
}
private bool _suppressID;
public Boolean SuppressID {
get {
return _suppressID;
}
set {
_suppressID = value;
}
}
private String _innerText;
public String InnerText {
get {
return _innerText;
}
set {
_innerText = value;
}
}
protected override void Render(HtmlTextWriter writer) {
if (Visible) {
if (!String.IsNullOrEmpty(ID) && !SuppressID) {
Attributes["id"] = ID;
}
foreach (String attributeName in Attributes.Keys) {
String value = Attributes[attributeName];
writer.AddAttribute(attributeName, value);
}
if (!String.IsNullOrEmpty(CssClass)) {
writer.AddAttribute("class", CssClass);
}
writer.RenderBeginTag(_tag);
if (InnerText != null) {
writer.WriteEncodedText(InnerText);
}
else {
RenderContents(writer);
}
writer.RenderEndTag();
}
}
}
Затем я сделал это для каждого тега. Это не самое элегантное решение (это еще одна библиотека классов, генерирующих HTML), но оно дает мне нужный мне контроль.
Когда я захочу использовать тег, я напишу следующее:
<%@ Register TagPrefix="myhtml" Assembly="MyAssembly" Namespace="MyNamespace.MyHTML" %>
<myhtml:Div runat="server" ID="_variableName" HtmlID="html_id_value" />
Это приведет к:
<div id="html_id_value"></div>