Pergunta

Eu estou escrevendo o método RenderContents() do meu controle de servidor ASP.NET. O método utiliza um objecto HtmlTextWriter para processar o conteúdo de saída. Para o controle Eu estou escrevendo, usando os métodos do HtmlTextWriter parece que vai exigir uma grande quantidade de linhas de código para abrir e fechar cada tag e adicionar todos os atributos para o fluxo. No final, eu sinto que eu vou acabar com código que é muito mais do que ele precisa ser.

Eu estava pensando que se eu usasse uma classe chainable como StringBuilder, meu código seria muito mais limpo para ler e mais fácil de escrever.

O que eu queria saber era, há alguma razão para usar o objeto HtmlTextWriter renderizar o conteúdo inteiro do meu controle? Outros que as verificações de segurança (estou assumindo) inclui certificar-se de que você faz tags não escrita na ordem errada ou criar marcação inválida, não vejo uma razão.

Parece que seria mais fácil simplesmente fazer algo como isto:

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();
}

Existe alguma razão para que esta seria uma má idéia?

Atualizar
Em resposta a resposta Mehrdad Afshari 's:
Eu não penso muito sobre os requisitos de memória de ter um objeto StringBuilder separado instanciado. Que tal fazer um wrapper para HtmlTextWriter para que ele possa ser encadeados de modo que uma corda extra não é feita.

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;
    }
}
Foi útil?

Solução

Eu trabalho em uma aplicação onde os desenvolvedores seguiu o caminho horrível você está explorando. Este remonta aos dias em que você tinha que escrever suas próprias DLLs ISAPI que cuspir código HTML. É uma dor de cabeça constante para o trabalho. Se o código é principalmente cordas, então algo está errado.

A maioria do código deste tipo que eu mudar Eu objetos de servidor instanciar, configure suas propriedades como desejado e, em seguida, dizer-lhes para .RenderControl (escritor). Isso torna o código muito mais fácil de ler e trabalhar com. Se houver um acerto de desempenho da sobrecarga que isso traz, estou disposto a aceitá-la (na verdade, o aplicativo geralmente corre mais rápido depois que eu fiz as minhas alterações, por isso informalmente este não é o caso, mas eu não tenho perfilado meu código).

Um simples desvantagem para embutir o seu material em cordas é quando a mudança padrões HTML. O trabalho de código I em foi escrito em 04/05, e desde então
tornou-se
e maiúsculas html tags não são kosher mais, etc. Se eles tivessem vindo a utilizar controles de servidor, esses controles de servidor mudaram seus html emitido sem nós a necessidade de fazer nada. Este é apenas um exemplo simples.

EDIT: Ah, e btw, BeginRender e EndRender não têm qualquer aplicação. Eles são espaços reservados para que você possa substituir e fornecer funcionalidade personalizada em uma classe derivada de HtmlTextWriter.

EDIT2: Às vezes é um pouco onerosa para sempre controles de servidor uso, como para recipientes e outras coisas. Eu estaria fazendo muita .Controls.Add () e, em seguida, tornar o recipiente mais tarde. Então, às vezes eu faço isso:

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

Como mencionado, este irá processar html correto, mesmo se o html de um div muda no futuro, porque eu não tem nenhum cordas codificados.

Outras dicas

Em termos de performance, isso vai exigir mais cópias de cadeia para ser feito. HtmlTextWriter escreve directamente para a memória intermédia de saída. StringBuilder por outro lado, tem o seu próprio buffer. Quando você chama ToString na StringBuilder, uma nova seqüência tem que ser construído e, em seguida, ele vai ser escrito para o buffer de saída por output.Write. Ele requer muito mais trabalho a ser feito.

Eu não acho que você deveria estar chamando BeginRender / EndRender, isso é feito pela página.

Não consigo ver como usando construtor corda iria salvar qualquer trabalho sobre o uso dos HtmlTextWriters próprios métodos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top