C#-以字符串形式编写HTML的面向对象方法?

C#-以字符串形式编写HTML的面向对象方法?,c#,html,oop,htmltextwriter,C#,Html,Oop,Htmltextwriter,我试图以编程方式递归地发送一封包含目录中所有dll文件及其版本的电子邮件。我想使用表格以HTML输出的形式发送电子邮件。有没有一种很好的面向对象的方法?我不喜欢手写所有的标签 比如: private string getHTMLString() { DirectoryInfo di = new DirectoryInfo("some directory"); FileInfo[] files = di.GetFiles("*.dll", SearchOption.AllDirec

我试图以编程方式递归地发送一封包含目录中所有dll文件及其版本的电子邮件。我想使用表格以HTML输出的形式发送电子邮件。有没有一种很好的面向对象的方法?我不喜欢手写所有的标签

比如:

private string getHTMLString()
{
    DirectoryInfo di = new DirectoryInfo("some directory");
    FileInfo[] files = di.GetFiles("*.dll", SearchOption.AllDirectories);
    foreach (FileInfo file in files)
    {
        Assembly assembly = Assembly.LoadFile(file.FullName);
        string version = assembly.GetName().Version.ToString();
    }
 }

标签是标签。你得写下来

您可以使用HtmlTextWriter进行实际的编写,但没有神奇的方法可以避免这种情况。

类似的事情

private string getHTMLString()
{
    DirectoryInfo di = new DirectoryInfo("some directory");
    FileInfo[] files = di.GetFiles("*.dll", SearchOption.AllDirectories);
    StringBuilder sb = new StringBuilder();
    sb.Append("<table>");
    foreach (FileInfo file in files)
    {
        Assembly assembly = Assembly.LoadFile(file.FullName);
        string version = assembly.GetName().Version.ToString();
        sb.AppendFormat("<tr><td>{0}</td><td>{1}</td></tr>", file.FullName, version);
    }
    sb.Append("</table>");
    return sb.ToString();

 }
私有字符串getHTMLString()
{
DirectoryInfo di=新的DirectoryInfo(“某个目录”);
FileInfo[]files=di.GetFiles(“*.dll”,SearchOption.AllDirectories);
StringBuilder sb=新的StringBuilder();
某人加上(“”);
foreach(文件中的文件信息文件)
{
Assembly=Assembly.LoadFile(file.FullName);
字符串版本=assembly.GetName().version.ToString();
sb.AppendFormat(“{0}{1}”,file.FullName,version);
}
某人加上(“”);
使某人返回字符串();
}
不是真正的“面向对象”,但我认为最符合逻辑


免责声明:手工编译

您所做的事情似乎足够简单,只需手动使用字符串缓冲区即可。如果这更复杂,我建议您使用模板引擎,例如。

您可以使用XmlWriter以更面向对象的方式执行此操作:

StringBuilder sb = new StringBuilder();
XmlWriter xmlWri = XmlWriter.Create(sb);
xmlWri.WriteStartElement("html");
{
    xmlWri.WriteStartElement("body");
    {
        xmlWri.WriteAttributeString("bgcolor", "black");

        // More html stuff
    }
    xmlWri.WriteEndElement(); // body
}
xmlWri.WriteEndElement(); // html
xmlWri.Flush();
xmlWri.Close();
string html = sb.ToString();

编辑:这样做会变得相当麻烦,将来如果你想更改HTML内容,你必须通过代码来完成。更好的方法是读入一个预格式化的HTML文档,该文档中的占位符映射到表中的列,因此您需要的只是一种方法来循环遍历所有列,并对HTML文档中的占位符进行查找/替换。

您实际上可以使用HtmlTextWriter并使用HtmlTextWriterTag枚举来创建标记,而不需要实际手写“”

例如:

StringBuilder sb = new StringBuilder();

using (HtmlTextWriter w = new HtmlTextWriter(new StringWriter(sb)))
{
      w.RenderBeginTag(HtmlTextWriterTag.P);

      w.AddStyleAttribute(HtmlTextWriterStyle.Color, "red");

      w.RenderBeginTag(HtmlTextWriterTag.Span);

      w.Write("This is some text");

      w.RenderEndTag();

      w.RenderEndTag();
 }

 string html = sb.ToString();

它不会自动为您创建HTML,但它确实可以帮助您以“更面向对象”的方式编写HTML,并且它将帮助您(不确保)编写有效的HTML(所有标记都有结束标记等)。

这可能有些过分,但您可以使用LINQ to XML生成HTML字符串。。。这是您的代码,使用LINQ和XElement生成一个简单的表

唯一需要注意的是空标记,它们在HTML中不能作为自动关闭标记。例如,空的TD:
new-XElement(“TD”)
将呈现为无效的HTML。您可以通过插入一个空字符串作为内容来解决此问题:
new-XElement(“td”,string.empty)
-这将输出


通过实例化System.Web.UI.WebControl.Table,添加TableRows和TableCells,然后将Table.RenderControl调用到HtmlTextWriter中,您可以实现OO,但公平地说:这太糟糕了:)


我目前正在写一个库,正好解决这个问题。它允许您使用集合初始值设定项构造HTML,因此它可以非常简洁。它还支持CSS样式、作为可选参数的元素属性等。它是LGPL,所以您可以在任何地方使用它

您的代码如下所示:

private string getHTMLString()
{
    DirectoryInfo di = new DirectoryInfo("some directory");
    FileInfo[] files = di.GetFiles("*.dll", SearchOption.AllDirectories);

    var table = new Table();

    foreach (FileInfo file in files)
    {
        Assembly assembly = Assembly.LoadFile(file.FullName);
        string version = assembly.GetName().Version.ToString();

        table.Add(new Tr { new Td { file.FullName }, new Td { version } });
    }

    return table.Render();
}

.

似乎是最直接的方法。我想写一些类似于HTMLTableClass的东西,它使用StringBuilder来完成上面的工作。我真的希望有一些神奇的内置库,但我想它只是不在那里。谢谢。我强烈建议在将文件名嵌入HTML之前对其执行HtmlEncode()。-1:如果可以的话,我会将其设置为-1/2-1用于在不使用任何HTML编码的情况下使用AppendFormat。根据file.FullName和version的内容,这可能会产生不正确的结果。是的,我个人认为,对于应用程序来说,上面的内容是多余的。使用文件或app.config中定义的模板是一个很好的建议,这取决于用例。模板可以工作,但您必须知道,您不仅仅使用字符串。您必须遵循HTML编码规则。使用DOM或HTML API可以帮到你。使用DOM可以防止你犯一些愚蠢的错误,比如没有逃过符号、不正确的嵌套、关闭错误的标记等等。我同意在可用的情况下使用DOM或HTML API。一旦你有了一个给定的文件名,最好将其转换为安全的HTML文本。诚然,文件名不能包含许多在呈现为HTML时有问题的字符,但它们可以包含一些字符,例如空格、单引号(')和符号。这可能是最“面向对象”的方式。但是是的。。吓人。这相当冗长,但如果你不想使用模板引擎,我认为这是最好的方法。它不会处理需要编码的特殊字符。什么不会?如果您需要对某些内容进行编码,只需使用
HttpServerUtility.HtmlEncode
我喜欢这样,它很优雅:)没有愚蠢的循环。
        var tbl = new System.Web.UI.WebControls.Table();

        DirectoryInfo di = new DirectoryInfo("some directory");
        FileInfo[] files = di.GetFiles("*.dll", SearchOption.AllDirectories);
        foreach (FileInfo file in files)
        {
            Assembly assembly = Assembly.LoadFile(file.FullName);
            string version = assembly.GetName().Version.ToString();

            var tr = new System.Web.UI.WebControls.TableRow();
            var tc = new System.Web.UI.WebControls.TableCell();
            tc.Text = HttpUtility.HtmlEncode(version);
            tr.Cells.Add(tc);
            tbl.Rows.Add(tr);
        }

        using (var ts = new StringWriter())
        using (var html = new System.Web.UI.HtmlTextWriter(ts))
        {
            // Not entirely sure about this part
            tbl.RenderControl(html);
            html.Flush();
            string htmlString = ts.ToString();
        }
private string getHTMLString()
{
    DirectoryInfo di = new DirectoryInfo("some directory");
    FileInfo[] files = di.GetFiles("*.dll", SearchOption.AllDirectories);

    var table = new Table();

    foreach (FileInfo file in files)
    {
        Assembly assembly = Assembly.LoadFile(file.FullName);
        string version = assembly.GetName().Version.ToString();

        table.Add(new Tr { new Td { file.FullName }, new Td { version } });
    }

    return table.Render();
}