【问题标题】:How can I create a formatted string out of a block of html?如何从 html 块中创建格式化字符串?
【发布时间】:2017-01-18 23:14:00
【问题描述】:

我需要向字符串列表的(字符串)成员提供可变数据位(电子邮件的“正文”),并尝试使用 string.format 构建它,但我得到,“) 预期”在此处的“http”部分:

string htmlBodyAmalgamation = string.Format(@"<html><body><img src=\"http://www.platypus.com/wp-
content/themes/platypus/images/pa_logo_notag.png\" alt=\"Platypus logo\" width=\"199\" height=\"130\" ><p>{0}</p>", body);

无论“http”前面有 0、1、2 还是 3 个回击(“\”),我都会收到错误消息。

如果没有可变部分(如果主体是静态的/预先知道的)我可以这样做:

List<String> htmlBody = new List<string>
    {
        "<html><body><img src=\"http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png\" alt=\"Platypus logo\" width=\"199\" height=\"130\" ><p>Your Platypus Price Push report is attached.</p>",
        "</body></html>"
    };
mailItem.HTMLBody = string.Join(Environment.NewLine, htmlBody.ToArray());

...它工作正常。

所以它试图通过 string.format 嵌入变量“body”值,这证明是有问题的:

string htmlBodyAmalgamation = string.Format(@"<html><body><img src=\"http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png\" alt=\"Platypus logo\" width=\"199\" height=\"130\" ><p>Your Platypus Price Push report is attached.</p>", body);
List<String> htmlBody = new List<string>
    {
        htmlBodyAmalgamation,
        "</body></html>"
    };

让 html 和 string.format 一起工作的诀窍是什么?

【问题讨论】:

  • 在最后一个示例中,您使用逐字运算符@ 并使用\ 转义。在这些字符串中,您实际上可以使用" 转义",使其变为""
  • 使用单引号似乎更简单,而且似乎有效。

标签: c# html winforms outlook string-formatting


【解决方案1】:

我想分享一个我大约一年前使用的优雅解决方案。 我们也将 HTML 模板用于电子邮件,并且发现 Razor 引擎实际上(显然)非常擅长这样做。

我们的代码如下:

    public string CompileMessage(string templateHtml, object modelClass)
    {
        try
        {
            TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration
            {
                Resolver = new TemplateResolver(),
                Language = Language.CSharp,
                Debug = true,
            };

            Razor.SetTemplateService(new TemplateService(templateConfig));

            return Razor.Parse(templateHtml, modelCLass);
        }
        catch (Exception ex)
        {
            Logger.Log4Net.Error("Failed to compile email template using Razor", ex);
            return "Error occurred (" + ex.Message + "). Check the logfile in the vicinity of " + DateTime.Now.ToLongTimeString() + ".";
        }
    }

好处:

  • 使用 Razor 为我们提供了类型安全性,即为模型提供“占位符”
  • 我们已经涵盖了 XSS 和类似的攻击,因为 Razor 总是会转义值,除非使用了 @Html.Raw()
  • 它使业务用户能够相对安全地编辑模板,而不必担心不符合 html 的字符
  • Razor 会在格式化字符串时处理文化/用户界面文化

【讨论】:

  • 这是一个 Windows 窗体应用程序。
  • @B.ClayShannon 您可以在 MVC 应用程序之外使用 Razor,它实际上是 RazorEngine 库。另见this SO answer
【解决方案2】:

看起来很简单 - 使用单引号而不是双引号,并省略反击:

string htmlBodyAmalgamation = string.Format(@"<html><body><img src='http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png' alt='Platypus logo' width='199' height='130' ><p>{0}</p>", body);

更简单的是,我可以去掉一些中间商,然后这样做:

mailItem.HTMLBody = string.Format(@"<html><body><img src='http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png' alt='Platypus logo' width='199' height='130' ><p>{0}</p></body></html>", body);

【讨论】:

  • 对于简单的 html 内容,使用字符串格式是完全可以的,但是对于像电子邮件模板这样的复杂场景,请考虑使用run-time T4 templates
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多