String.Format在HTML电子邮件模板的样式部分失败

5

我正在使用Bodybuilder和邮件发送服务发送HTML电子邮件模板。我使用了这个链接学习。

https://www.c-sharpcorner.com/article/send-email-using-templates-in-asp-net-core-applications/

无论如何,我使用外部服务 (https://topol.io/) 创建了我的电子邮件模板。

当我尝试使用第一个链接中引用的 String.Format 命令来使用生成的 HTML 文件时,它会给我带来错误。我最终发现是这段代码导致了 String.Format 失败。

这是我的 C# 代码,通常适用于其他 HTML 模板:

using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
            {
                builder.HtmlBody = SourceReader.ReadToEnd();
            }

string messagebody = string.Format(builder.HtmlBody,
                    //Not important
                    );

现在,HTML中的这个样式代码会导致String.Format崩溃(或者是bodybuilder,我不确定哪一个有问题,在string.format处失败)。
<style type="text/css">
        #outlook a {
            padding: 0;
        }

        .ReadMsgBody {
            width: 100%;
        }

        .ExternalClass {
            width: 100%;
        }

            .ExternalClass * {
                line-height: 100%;
            }

        body {
            margin: 0;
            padding: 0;
            -webkit-text-size-adjust: 100%;
            -ms-text-size-adjust: 100%;
        }

        table, td {
            border-collapse: collapse;
            mso-table-lspace: 0pt;
            mso-table-rspace: 0pt;
        }

        img {
            border: 0;
            height: auto;
            line-height: 100%;
            outline: none;
            text-decoration: none;
            -ms-interpolation-mode: bicubic;
        }

        p {
            display: block;
            margin: 13px 0;
        }
    </style>
    <!--[if !mso]><!-->
    <style type="text/css">
        @media only screen and (max-width:480px) {
            @-ms-viewport {
                width: 320px;
            }

            @viewport {
                width: 320px;
            }
        }
    </style>
    <style type="text/css">
        @media only screen and (min-width:480px) {
            .mj-column-per-100 {
                width: 100% !important;
            }

            .mj-column-per-60 {
                width: 60% !important;
            }

            .mj-column-per-40 {
                width: 40% !important;
            }

            .mj-column-per-50 {
                width: 50% !important;
            }
        }
    </style>
    <!--[if mso]><xml>
            <o:OfficeDocumentSettings>
            <o:AllowPNG/>
            <o:PixelsPerInch>96</o:PixelsPerInch>
            </o:OfficeDocumentSettings></xml><![endif]-->
    <!--[if lte mso 11]><style type="text/css">.outlook-group-fix {    width:100% !important;  }</style>
        <![endif]-->
    <!--[if !mso]><!-->
    <link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700" rel="stylesheet" type="text/css">
    <link href="https://fonts.googleapis.com/css?family=Merriweather" rel="stylesheet" type="text/css">
    <style type="text/css">
        @import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700);
        @import url(https://fonts.googleapis.com/css?family=Merriweather);
    </style>
    <!--<![endif]-->

有什么想法吗?如果失败的原因不明显,我愿意接受如何将此CSS部分外部化的建议。


解决这个问题最优雅的方法是使用CSS内联器。没有<style>标签,您将删除所有{和}符号。 - Mateech
3个回答

5

您之所以会出现这个错误,是因为在 string.Format 中花括号用作值参数的占位符。

解决问题的一种方法是将花括号替换为双花括号:

using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
            {
                builder.HtmlBody = SourceReader.ReadToEnd();
            }

string htmlBody = builder.HtmlBody.Replace("{", "{{").Replace("}","}}")
string messagebody = string.Format(htmlBody,
                    //Not important
                    );

@dave317,每次读取模板时都这样做是低效的,而且你怎么知道哪些大括号是占位符,哪些不是。如果没有占位符,你根本不需要使用 String.Format - Jodrell
我同意,但当我写答案时,我将OP的评论//not important解释为对问题不重要,但对他的代码很重要。 - matramos
当然!我正在使用占位符。我应该意识到这一点。现在感到非常无语。我将用双括号替换单括号,看看是否有效。我会在模板上进行操作。你是正确的Mat,//not important是一些占位符信息。 - dave317

2
您正在对包含大量CSS定义的字符串调用String.Format。CSS定义包括许多{}对。 String.Format{}对解释为占位符以进行替换,但这不是它们在您的字符串中表示的内容。
在这种情况下,为什么需要使用String.Format呢?
为什么不改为:
builder.HtmlBody = File.ReadAllText(pathToFile);

如果//无关紧要实际上很重要,您可以在模板中转义括号,如此回答。因此,您不想替换的大括号分别变为'{{''}}'
基本上,在模板上运行另一个准备步骤,将{替换为{{,将}替换为}},除非它们表示您想要替换的占位符。

0
问题在于CSS部分的{}。对于string.Format,它们表示占位符,但是CSS代码不是有效的占位符。
如果您确实需要使用string.Format替换一些文本,并且您总是通过string.Format推送输入文件,则可以将输入的每个{}分别替换为{{}},在您实际希望在最终结果中出现{的位置使用{}进行替换。但不确定这与Bodybuilder的兼容性如何。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接