c# - Escreva HTML na string

Translate

Eu tenho um código como este. Existe uma maneira de tornar mais fácil escrever e manter? Usando C # .NET 3.5.

string header(string title)
{
    StringWriter s = new StringWriter();
    s.WriteLine("{0}","<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
    s.WriteLine("{0}", "<html>");
    s.WriteLine("<title>{0}</title>", title);
    s.WriteLine("{0}","<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">");
    s.WriteLine("{0}", "</head>");
    s.WriteLine("{0}", "<body>");
    s.WriteLine("{0}", "");
}

Eu também poderia simplesmente escrever:

s.WriteLine("{0}", @"blah blah

many
new
lines
blah UHY#$&_#$_*@Y KSDSD<>\t\t\t\t\t\tt\t\t\\\t\t\t\t\\\h\th'\h't\th
hi
done"); 

Vai funcionar, mas preciso substituir todos"com"".

This question and all comments follow the "Attribution Required."

Todas as respostas

lc.
Translate

Você provavelmente é melhor usar umHtmlTextWriterou umXMLWriterdo que uma planícieStringWriter. Eles vão cuidar de escapar para você, bem como garantir que o documento esteja bem formado.

Esta páginamostra os fundamentos do uso doHtmlTextWriterclasse, cuja essência é:

StringWriter stringWriter = new StringWriter();

using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
{
    writer.AddAttribute(HtmlTextWriterAttribute.Class, classValue);
    writer.RenderBeginTag(HtmlTextWriterTag.Div); // Begin #1

    writer.AddAttribute(HtmlTextWriterAttribute.Href, urlValue);
    writer.RenderBeginTag(HtmlTextWriterTag.A); // Begin #2

    writer.AddAttribute(HtmlTextWriterAttribute.Src, imageValue);
    writer.AddAttribute(HtmlTextWriterAttribute.Width, "60");
    writer.AddAttribute(HtmlTextWriterAttribute.Height, "60");
    writer.AddAttribute(HtmlTextWriterAttribute.Alt, "");

    writer.RenderBeginTag(HtmlTextWriterTag.Img); // Begin #3
    writer.RenderEndTag(); // End #3

    writer.Write(word);

    writer.RenderEndTag(); // End #2
    writer.RenderEndTag(); // End #1
}
// Return the result.
return stringWriter.ToString();
Fonte
Translate

Quando lido com esse problema em outras linguagens, procuro uma separação de código e HTML. Algo como:

1.) Crie um modelo HTML. usar[varname]marcadores de posição para marcar o conteúdo substituído / inserido.
2.) Preencha suas variáveis de modelo a partir de uma matriz ou estrutura / mapeamento / dicionário

Write( FillTemplate(myHTMLTemplate, myVariables) ) # pseudo-code
Fonte
Translate

Eu sei que você perguntou sobre C #, mas se você está disposto a usar qualquer linguagem .Net, então eu recomendo o Visual Basic para este problema exato. Visual Basic tem um recurso chamado XML Literals que permitirá a você escrever código como este.

Module Module1

    Sub Main()

        Dim myTitle = "Hello HTML"
        Dim myHTML = <html>
                         <head>
                             <title><%= myTitle %></title>
                         </head>
                         <body>
                             <h1>Welcome</h1>
                             <table>
                                 <tr><th>ID</th><th>Name</th></tr>
                                 <tr><td>1</td><td>CouldBeAVariable</td></tr>
                             </table>
                         </body>
                     </html>

        Console.WriteLine(myHTML)
    End Sub

End Module

Isso permite que você escreva HTML direto com lacunas de expressão no antigo estilo ASP e torna seu código super legível. Infelizmente, esse recurso não está em C #, mas você pode escrever um único módulo em VB e adicioná-lo como uma referência ao seu projeto C #.

Escrever no Visual Studio também permite o recuo adequado para a maioria dos literais XML e conjuntos de expressão. O recuo para os orifícios de expressão é melhor no VS2010.

Fonte
Translate

Use umXDocumentpara criar o DOM e, em seguida, escreva-o usando umXmlWriter. Isso lhe dará uma notação maravilhosamente concisa e legível, bem como uma saída bem formatada.

Faça este programa de amostra:

using System.Xml;
using System.Xml.Linq;

class Program {
    static void Main() {
        var xDocument = new XDocument(
            new XDocumentType("html", null, null, null),
            new XElement("html",
                new XElement("head"),
                new XElement("body",
                    new XElement("p",
                        "This paragraph contains ", new XElement("b", "bold"), " text."
                    ),
                    new XElement("p",
                        "This paragraph has just plain text."
                    )
                )
            )
        );

        var settings = new XmlWriterSettings {
            OmitXmlDeclaration = true, Indent = true, IndentChars = "\t"
        };
        using (var writer = XmlWriter.Create(@"C:\Users\wolf\Desktop\test.html", settings)) {
            xDocument.WriteTo(writer);
        }
    }
}

Isso gera a seguinte saída:

<!DOCTYPE html >
<html>
    <head />
    <body>
        <p>This paragraph contains <b>bold</b> text.</p>
        <p>This paragraph has just plain text.</p>
    </body>
</html>
Fonte
Translate

Você poderia usarSystem.Xml.Linqobjetos. Eles foram totalmente redesenhados a partir do antigoSystem.Xmldias que tornavam a construção de XML do zero realmente irritante.

Além do doctype, eu acho, você poderia facilmente fazer algo como:

var html = new XElement("html",
    new XElement("head",
        new XElement("title", "My Page")
    ),
    new XElement("body",
        "this is some text"
    )
);
Fonte
Translate
return string.Format(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01//EN""      ""http://www.w3.org/TR/html4/strict.dtd"">
<html>
<title>{0}</title>
<link rel=""stylesheet"" type=""text/css"" href=""style.css"">
</head>
<body>
", title);
Fonte
Translate

A maneira mais direta é usar um objeto XmlWriter. Isso pode ser usado para produzir HTML válido e cuidará de todas as sequências de escape desagradáveis para você.

Fonte
Translate

Você pode usarModelos T4para gerar Html (ou qualquer) a partir do seu código. Veja isso:http://msdn.microsoft.com/en-us/library/ee844259.aspx

Fonte
Translate

Se você está procurando criar um documento HTML semelhante a como criaria um documento XML em C #, pode experimentar a biblioteca de código aberto da Microsoft, aPacote de Agilidade Html.

Ele fornece um objeto HtmlDocument que tem uma API muito semelhante aoSystem.Xml.XmlDocumentclasse.

Fonte
Translate

Você pode usar ASP.NET para gerar seu HTML fora do contexto de páginas da web.Aqui está um artigoisso mostra como isso pode ser feito.

Fonte
Translate

Você pode usar algumas bibliotecas de código aberto de terceiros para gerar HTML verificado (X) com tipo forte, comoFramework CityLizardou Sharp DOM.

AtualizarPor exemplo

html
    [head
        [title["Title of the page"]]
        [meta_(
            content: "text/html;charset=UTF-8",
            http_equiv: "Content-Type")
        ]
        [link_(href: "css/style.css", rel: "stylesheet", type: "text/css")]
        [script_(type: "text/javascript", src: "/JavaScript/jquery-1.4.2.min.js")]
    ]
    [body
        [div
            [h1["Test Form to Test"]]
            [form_(action: "post", id: "Form1")
                [div
                    [label["Parameter"]]
                    [input_(type: "text", value: "Enter value")]
                    [input_(type: "submit", value: "Submit!")]
                ]
            ]
            [div
                [p["Textual description of the footer"]]
                [a_(href: "http://google.com/")
                    [span["You can find us here"]]
                ]
                [div["Another nested container"]]
            ]
        ]
    ];
Fonte
Translate

Esta não é uma solução genérica, no entanto, se o seu objetivo é ter ou manter modelos de e-mail, então System.Web tem uma classe interna chamadaMailDefinition. Esta classe é usada pelos controles de associação ASP.NET para criar emails em HTML.

Faz o mesmo tipo de 'string substituir' as coisas mencionadas acima, mas empacota tudo em uma MailMessage para você.

Aqui está um exemplo do MSDN:

ListDictionary replacements = new ListDictionary();
replacements.Add("<%To%>",sourceTo.Text);
replacements.Add("<%From%>", md.From);
System.Net.Mail.MailMessage fileMsg;
fileMsg = md.CreateMailMessage(toAddresses, replacements, emailTemplate, this); 
return fileMsg;
Fonte
Translate

Com a introdução do Razor no ASP.net MVC, a melhor maneira de escrever HTML em C # é com o Razor Engine.

string templatePath = [email protected]"{Directory.GetCurrentDirectory()}\EmailTemplates"; 

IRazorLightEngine engine = EngineFactory.CreatePhysical(templatePath); 

var model = new Notification 
{ 
       Name = "Jone", 
       Title = "Test Email", 
       Content = "This is a test" 
}; 

string result = engine.Parse("template.cshtml", model); 

Modelo:

<h2>Dear @Model.Name, you have a notification.</h2> 

<h1>@Model.Title</h1> 
<p>@Model.Content</p> 

<p>Date:@DateTime.Now</p> 

Para uma amostra completa, vejaaqui

Fonte
Translate

Você poderia escrever suas próprias classes com seu método Render e outros atributos, para evitar uma grande confusão se você usá-lo muito, e então usar o HTMLWriter ou o xmlwriter também. Essa lógica é usada nas páginas asp.net, você pode herdar de webControl e substituir ométodo de renderização, o que é ótimo se você estiver desenvolvendo controles do lado do servidor.
estepoderia ser um bom exemplo.

Saudações

Fonte
Translate

Realmente depende do que você está procurando e, especificamente, que tipo de desempenho você realmente precisa oferecer.

Já vi soluções admiráveis para o desenvolvimento de HTML fortemente tipado (modelos de controle completos, sejam eles ASP.NET Web Controls ou semelhantes) que apenas adicionam uma complexidade incrível a um projeto. Em outras situações, é perfeito.

Em ordem de preferência no mundo C #,

  • Controles da Web ASP.NET
  • Primitivos ASP.NET e controles HTML
  • XmlWriter e / ou HtmlWriter
  • Se estiver fazendo o desenvolvimento do Silverlight com interoperabilidade HTML, considere algo fortemente tipado comoTexto do link
  • StringBuilder e outros superprimitivos
Fonte
Translate

Escrevi essas aulas que me serviram bem. É simples, mas pragmático.

public class HtmlAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }

    public HtmlAttribute(string name) : this(name, null) { }

    public HtmlAttribute(
        string name,
        string @value)
    {
        this.Name = name;
        this.Value = @value;
    }

    public override string ToString()
    {
        if (string.IsNullOrEmpty(this.Value))
            return this.Name;

        if (this.Value.Contains('"'))
            return string.Format("{0}='{1}'", this.Name, this.Value);

        return string.Format("{0}=\"{1}\"", this.Name, this.Value);
    }
}

public class HtmlElement
{
    protected List<HtmlAttribute> Attributes { get; set; }
    protected List<object> Childs { get; set; }
    public string Name { get; set; }
    protected HtmlElement Parent { get; set; }

    public HtmlElement() : this(null) { }

    public HtmlElement(string name, params object[] childs)
    {
        this.Name = name;
        this.Attributes = new List<HtmlAttribute>();
        this.Childs = new List<object>();

        if (childs != null && childs.Length > 0)
        {
            foreach (var c in childs)
            {
                Add(c);
            }
        }
    }

    public void Add(object o)
    {
        var a = o as HtmlAttribute;
        if (a != null)
            this.Attributes.Add(a);
        else
        {
            var h = o as HtmlElement;
            if (h != null && !string.IsNullOrEmpty(this.Name))
            {
                h.Parent = this;
                this.Childs.Add(h);
            }
            else
                this.Childs.Add(o);
        }
    }

    public override string ToString()
    {
        var result = new StringBuilder();

        if (!string.IsNullOrEmpty(this.Name))
        {
            result.Append(string.Format("<{0}", this.Name));
            if (this.Attributes.Count > 0)
            {
                result.Append(" ");
                foreach (var attr in this.Attributes)
                {
                    result.Append(attr.ToString());
                    result.Append(" ");
                }

                result = new StringBuilder(result.ToString().TrimEnd(' '));
            }

            if (this.Childs.Count == 0)
            {
                result.Append(" />");
            }
            else
            {
                result.AppendLine(">");

                foreach (var c in this.Childs)
                {
                    var cParts = c.ToString().Split('\n');

                    foreach (var p in cParts)
                    {
                        result.AppendLine(string.Format("{0}", p));
                    }
                }

                result.Append(string.Format("</{0}>", this.Name));
            }
        }
        else
        {
            foreach (var c in this.Childs)
            {
                var cParts = c.ToString().Split('\n');

                foreach (var p in cParts)
                {
                    result.AppendLine(string.Format("{0}", p));
                }
            }
        }

        var head = GetHeading(this);

        var ps = result.ToString().Split('\n');
        return string.Join("\r\n", (from p in ps select head + p.TrimEnd('\r')).ToArray());
    }

    string GetHeading(HtmlElement h)
    {
        if (h.Parent != null)
            return "    ";
        else
            return string.Empty;
    }
}
Fonte
MMA
Translate

HSharp é uma biblioteca usada para analisar linguagem de marcação como HTML de forma fácil e rápida. Instalar:PM> Install-Package Obisoft.HSharp

        var Document = new HDoc(DocumentOptions.BasicHTML);
        Document["html"]["body"].AddChild("div");
        Document["html"]["body"]["div"].AddChild("a", new HProp("href", "/#"));
        Document["html"]["body"]["div"].AddChild("table");
        Document["html"]["body"]["div"]["table"].AddChildren(
         new HTag("tr"),
         new HTag("tr", "SomeText"),
         new HTag("tr", new HTag("td")));
        var Result = Document.GenerateHTML();
        Console.WriteLine(Result);

e saída:

<html>
<head>
<meta charset="utf-8"></meta><title>
Example </title>
</head>
<body>
<div>
<a href="/#"></a><table>
<tr></tr><tr>
SomeText </tr>
<tr>
<td></td></tr>
</table>
</div>
</body>
</html>
Fonte
Translate

Eu estava procurando por algo parecido com jquery para gerar dom em C # (não preciso analisar). Infelizmente, não tive sorte em encontrar uma solução leve, então criei esta classe simples que é herdada de System.Xml.Linq.XElement. A principal característica é que você pode encadear o operador como ao usar jquery em javascript para que seja mais fluente. Não tem todos os recursos, mas faz o que preciso e, se houver interesse, posso iniciar um git.

public class DomElement : XElement
{
    public DomElement(string name) : base(name)
    {
    }

    public DomElement(string name, string value) : base(name, value)
    {
    }

    public DomElement Css(string style, string value)
    {
        style = style.Trim();
        value = value.Trim();
        var existingStyles = new Dictionary<string, string>();
        var xstyle = this.Attribute("style");
        if (xstyle != null)
        {
            foreach (var s in xstyle.Value.Split(';'))
            {
                var keyValue = s.Split(':');
                existingStyles.Add(keyValue[0], keyValue.Length < 2 ? null : keyValue[1]);
            }
        }

        if (existingStyles.ContainsKey(style))
        {
            existingStyles[style] = value;
        }
        else
        {
            existingStyles.Add(style, value);
        }

        var styleString = string.Join(";", existingStyles.Select(s => $"{s.Key}:{s.Value}"));
        this.SetAttributeValue("style", styleString);

        return this;
    }

    public DomElement AddClass(string cssClass)
    {
        var existingClasses = new List<string>();
        var xclass = this.Attribute("class");
        if (xclass != null)
        {
            existingClasses.AddRange(xclass.Value.Split());
        }

        var addNewClasses = cssClass.Split().Where(e => !existingClasses.Contains(e));
        existingClasses.AddRange(addNewClasses);

        this.SetAttributeValue("class", string.Join(" ", existingClasses));
        return this;
    }

    public DomElement Text(string text)
    {
        this.Value = text;
        return this;
    }

    public DomElement Append(string text)
    {
        this.Add(text);
        return this;
    }

    public DomElement Append(DomElement child)
    {
        this.Add(child);
        return this;
    }
}

Amostra:

void Main()
{
    var html = new DomElement("html")
        .Append(new DomElement("head"))
        .Append(new DomElement("body")
            .Append(new DomElement("p")
                .Append("This paragraph contains")
                .Append(new DomElement("b", "bold"))
                .Append(" text.")
                )
            .Append(new DomElement("p").Text("This paragraph has just plain text"))
            )
        ;

    html.ToString().Dump();

    var table = new DomElement("table").AddClass("table table-sm").AddClass("table-striped")
            .Append(new DomElement("thead")
                .Append(new DomElement("tr")
                    .Append(new DomElement("td").Css("padding-left", "15px").Css("color", "red").Css("color", "blue")
                        .AddClass("from-now")
                        .Append(new DomElement("div").Text("Hi there"))
                        .Append(new DomElement("div").Text("Hey there"))
                        .Append(new DomElement("div", "Yo there"))
                        )
                )
            )
        ;
    table.ToString().Dump();
}

saída do código acima:

<html>
  <head />
  <body>
    <p>This paragraph contains<b>bold</b> text.</p>
    <p>This paragraph has just plain text</p>
  </body>
</html>
<table class="table table-sm table-striped">
  <thead>
    <tr>
      <td style="padding-left:15px;color:blue" class="from-now">
        <div>Hi there</div>
        <div>Hey there</div>
        <div>Yo there</div>
      </td>
    </tr>
  </thead>
</table>
Fonte
Leave a Reply
You must be logged in to post a answer.
Sobre o autor