【问题标题】:Using HtmlTextWriter to Render Server Controls?使用 HtmlTextWriter 呈现服务器控件?
【发布时间】:2010-10-04 03:10:32
【问题描述】:

我正在编写我的 ASP.NET 服务器控件的 RenderContents() 方法。该方法使用HtmlTextWriter 对象来呈现输出内容。对于我正在编写的控件,使用HtmlTextWriter 的方法似乎需要很多代码行来打开和关闭每个标签并将每个属性添加到流中。最后,我觉得我最终会得到比需要的更长的代码。

我在想,如果我使用 StringBuilder 之类的可链接类,我的代码会更易读、更易编写。

我想知道的是,是否有任何理由使用HtmlTextWriter 对象来呈现我的整个控件的内容?除了安全检查(我假设)之外,它还包括确保您不会以错误的顺序编写标签或创建无效标记,我看不出任何原因。

似乎只做这样的事情会更容易:

protected override void RenderContents(HtmlTextWriter output)
{
    StringBuilder s = new StringBuilder();
    s.Append("lots")
     .Append("of")
     .Append("strings");

    output.BeginRender();
    output.Write(s.ToString());
    output.EndRender();
}

有什么理由说明这是个坏主意吗?

更新
回复Mehrdad Afshari的回答:
我没有过多考虑实例化单独的StringBuilder 对象的内存要求。为 HtmlTextWriter 制作一个包装器怎么样,这样它就可以被链接起来,这样就不会产生额外的字符串了。

public class ChainedHtmlTextWriter
{
    private HtmlTextWriter _W;
    public ChainedHtmlTextWriter(HtmlTextWriter writer)
    {
        _W = writer;
    }

    public ChainedHtmlTextWriter Write<T>(T value) 
    { 
        _W.Write(value); 
        return this; 
    }

    public ChainedHtmlTextWriter WriteLine<T>(T value)
    {
        _W.WriteLine(value);
        return this;
    }
}

【问题讨论】:

  • 也许需要一个更现实的例子

标签: asp.net stringbuilder servercontrols htmltextwriter method-chaining


【解决方案1】:

我正在开发一个应用程序,其中开发人员遵循您正在探索的可怕路径。这让人回想起您必须编写自己的 ISAPI dll 来输出 html 代码的日子。工作总是让人头疼。如果您的代码主要是字符串,那么就有问题了。

我更改的大多数这种类型的代码都会实例化服务器对象,根据需要配置它们的属性,然后将它们告诉 .RenderControl(writer)。这使得代码更容易阅读和使用。如果这带来的开销会对性能造成影响,我愿意接受(事实上,在我进行更改后,应用程序通常运行得更快,所以有趣的是,情况并非如此,但我没有分析过我的代码)。

在字符串中硬编码你的东西的一个简单缺点是当 HTML 标准发生变化时。我工作的代码是在 04/05 编写的,从那时起
变成了
并且大写的 html 标签不再是 kosher 了,等等。如果他们一直在使用服务器控件,那些服务器控件已经改变了他们的输出 html 而我们不需要做任何事情。这只是一个简单的例子。

编辑:哦,顺便说一句,BeginRender 和 EndRender 没有任何实现。它们是您在 HtmlTextWriter 派生类中覆盖和提供自定义功能的占位符。

EDIT2:有时总是使用服务器控件有点麻烦,比如容器和其他东西。我会做很多 .Controls.Add() ,然后再渲染容器。所以有时我会这样做:

writer.AddAttribute(HtmlTextWriterAttribute.Class, "myContainerClass");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
// do some stuff, .RenderControl on some other controls, etc.
writer.RenderEndTag();

如前所述,即使 div 的 html 将来发生变化,这也会呈现正确的 html,因为我没有任何硬编码字符串。

【讨论】:

  • 是的,是的,哦,是的!我希望我能 +10 这个答案。
  • 这不仅仅是关于“如果 div 的 html 将来发生变化”,它还与字符串的不变性有关。
  • 这就是为什么我用“一个简单的缺点”作为开头。有很多缺点。我只是列出了一个简单的例子。
【解决方案2】:

在性能方面,这将需要完成更多的字符串副本。 HtmlTextWriter 直接写入输出缓冲区。另一方面,StringBuilder 有自己的缓冲区。当您在StringBuilder 上调用ToString 时,必须构建一个新字符串,然后output.Write 将其写入输出缓冲区。这需要做更多的工作。

【讨论】:

  • +1,并且 HtmlTextWriter 有很多额外的方法可以帮助您确保输出格式正确的 HTML。
【解决方案3】:

我认为您不应该调用 BeginRender/EndRender,这是由页面完成的。

我看不出使用字符串生成器如何比使用 HtmlTextWriters 自己的方法节省任何工作。

【讨论】:

  • 根据我阅读 MSDN 文档的理解,每当要呈现控件时,都应该调用 BeginRender/EndRender 方法。
  • 你说的很对,这是官方的说法,我看不出它们在现实世界中有什么用,我从来没有在我的控件中调用它们。
猜你喜欢
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多