Использование HtmlTextWriter для рендеринга серверных элементов управления?

StackOverflow https://stackoverflow.com/questions/489691

Вопрос

Я пишу 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();
}

Есть ли какая-то причина, по которой это было бы плохой идеей?

Обновить
В ответ на Мехрдад Афшариответ 's:
Я не особо задумывался о требованиях к памяти, связанных с наличием отдельного 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;
    }
}
Это было полезно?

Решение

Я работаю над приложением, разработчики которого пошли по тому ужасному пути, который вы исследуете.Это возвращает к тем дням, когда вам приходилось писать свои собственные библиотеки DLL ISAPI, которые выдавали html-код.Работать с этим - постоянная головная боль.Если ваш код в основном состоит из строк, значит, что-то не так.

Большую часть кода этого типа, который я изменяю, я создаю экземпляры серверных объектов, настраиваю их свойства по желанию, а затем передаю их в .RenderControl(writer).Это значительно облегчает чтение кода и работу с ним.Если это приводит к снижению производительности из-за накладных расходов, я готов принять это (на самом деле, приложение обычно работает быстрее после того, как я внес свои изменения, так что, как ни странно, это не так, но я не профилировал свой код).

Один простой недостаток жесткого кодирования ваших материалов в строках заключается в изменении стандартов HTML.Код, над которым я работаю, был написан 04/05, и с тех пор <BR> стал <br /> и заглавные html-теги больше не являются кошерными и т.д.Если бы они использовали серверные элементы управления, эти серверные элементы управления изменили бы свой выводимый HTML-код без необходимости нам что-либо делать.Это всего лишь один простой пример.

Редактировать:Да, и кстати, BeginRender и EndRender не имеют никакой реализации.Они являются заполнителями, которые вы можете переопределить и предоставить пользовательскую функциональность в классе, производном от HtmlTextWriter.

РЕДАКТИРОВАТЬ 2:Иногда это немного обременительно для всегда используйте серверные элементы управления, например, для контейнеров и прочего.Я бы сделал много .Controls.Add(), а затем отрисовал контейнер позже.Поэтому иногда я делаю это:

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

Как уже упоминалось, это приведет к отображению правильного html, даже если html div изменится в будущем, потому что у меня нет никаких жестко закодированных строк.

Другие советы

С точки зрения производительности для этого потребуется выполнить больше копий строк. HtmlTextWriter записывает непосредственно в выходной буфер. StringBuilder с другой стороны, имеет свой собственный буфер.Когда ты позвонишь ToString на StringBuilder, необходимо создать новую строку , а затем она будет записана в выходной буфер с помощью output.Write.Для этого требуется проделать гораздо больше работы.

Я не думаю, что вам следует вызывать BeginRender / EndRender, это делается страницей.

Я не вижу, как использование string builder сэкономило бы какую-либо работу по сравнению с использованием собственных методов HtmlTextWriters.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top