代码之家  ›  专栏  ›  技术社区  ›  Dan Herbert

使用HtmlTextWriter渲染服务器控件?

  •  5
  • Dan Herbert  · 技术社区  · 17 年前

    我正在写 RenderContents() 我的ASP。NET服务器控件。该方法使用 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 的答案:
    我没有过多考虑单独使用内存的要求 字符串拼接 对象实例化。为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;
        }
    }
    
    3 回复  |  直到 9 年前
        1
  •  10
  •   ChrisN    17 年前

    我在一个应用程序上工作,开发人员遵循了你正在探索的可怕道路。这让人想起了你不得不编写自己的ISAPI dll来吐出html代码的日子。这是一个经常令人头疼的工作。如果你的代码主要是字符串,那么就有问题了。

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

    用字符串硬编码的一个简单缺点是当HTML标准发生变化时。我编写的代码是在04/05年编写的,从那时起<BR>已成为<br/>大写的html标签不再合法,等等。如果他们一直在使用服务器控件,那么这些服务器控件已经更改了他们输出的html,而我们不需要做任何事情。这只是一个简单的例子。

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

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

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

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

        2
  •  4
  •   Mehrdad Afshari    17 年前

    在性能方面,这将需要完成更多的字符串复制。 HtmlTextWriter 直接写入输出缓冲区。 StringBuilder 另一方面,它有自己的缓冲区。当你打电话的时候 ToString 字符串拼接 ,必须构建一个新字符串,然后通过以下方式将其写入输出缓冲区 output.Write 这需要做更多的工作。

        3
  •  1
  •   AnthonyWJones    17 年前

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

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

    推荐文章