自我关闭Html通用控件?

我正在写一些代码来为后面的代码中的head标签添加一个链接标签…即

HtmlGenericControl css = new HtmlGenericControl("link"); css.Attributes["rel"] = "Stylesheet"; css.Attributes["type"] = "text/css"; css.Attributes["href"] = String.Format("/Assets/CSS/{0}", cssFile); 

尝试实现类似……

  

我正在使用HtmlGenericControl实现这个…我遇到的问题是控件最终呈现为……

  

我似乎无法找到我不想渲染的附加 ,我认为它应该是对象的属性。

我错过了什么,或者这个控件不可能吗?

谢谢

我认为你必须从HtmlGenericControl派生,并覆盖Render方法。

然后你就可以自己写出“/>”(或者你可以使用HtmlTextWriter的SelfClosingTagEnd常量)。

编辑: 这是一个例子 (在VB中)

在尝试为umbraco.library:RegisterStyleSheetFile(string key, string url)写一个变通方法时umbraco.library:RegisterStyleSheetFile(string key, string url)我最终得到了与OP相同的问题并找到了以下内容。

根据规范 , link标签是一个void元素。 它不能有任何内容,但可以自我关闭。 W3Cvalidation器未将validation为正确的html5。

显然地

 HtmlGenericControl css = new HtmlGenericControl("link"); 

默认情况下呈现为 。 使用链接标记的特定控件解决了我的问题:

 HtmlLink css = new HtmlLink(); 

它产生标记 ,它被validation为正确的xhtml和html5。

除了link之外 , System.Web.UI.HtmlControls还包含其他void元素控件的类,例如imginputmeta

或者,您可以使用Page.ParseControl(string) ,它为您提供与您传递的字符串相同内容的控件。

我实际上在我当前的项目中做了同样的事情。 当然它需要引用当前页面(处理程序),但这不应该造成任何问题。

正如我所看到的,这种方法中唯一需要注意的是,你没有得到任何“OO”方法来创建你的控件(例如control.Attributes.Add("href", theValue")等)

我刚刚在另一个论坛上根据Ragaraths的评论为此创建了一个解决方案:

http://forums.asp.net/p/1537143/3737667.aspx

用这个覆盖HtmlGenericControl

 protected override void Render(HtmlTextWriter writer) { if (this.Controls.Count > 0) base.Render(writer); // render in normal way else { writer.Write(HtmlTextWriter.TagLeftChar + this.TagName); // render opening tag Attributes.Render(writer); // Add the attributes. writer.Write(HtmlTextWriter.SelfClosingTagEnd); // render closing tag } writer.Write(Environment.NewLine); // make it one per line } 

略带苛刻的方式。

  • 将控件放在PlaceHolder元素中。
  • 在劫持PlaceHolder的render方法背后的代码中。
  • 完全按照您的意愿渲染PlaceHolders内容。

这是特定于页面/控件的,不需要任何覆盖。 因此它对您系统的其余部分影响最小。

  
protected void Page_Init(object sender, EventArgs e) { myPlaceHolder.SetRenderMethodDelegate(ClosingRenderMethod); } protected void ClosingRenderMethod(HtmlTextWriter output, Control container) { var voidTags = new HashSet(StringComparer.InvariantCultureIgnoreCase) { "br", "hr", "link", "img" }; foreach (Control child in container.Controls) { var generic = child as HtmlGenericControl; if (generic != null && voidTags.Contains(generic.TagName)) { output.WriteBeginTag(generic.TagName); output.WriteAttribute("id", generic.ClientID); generic.Attributes.Render(output); output.Write(HtmlTextWriter.SelfClosingTagEnd); } else { child.RenderControl(output); } } }