I am sending HTML email template using Bodybuilder and a mail sending service. I used this link learn.
https://www.c-sharpcorner.com/article/send-email-using-templates-in-asp-net-core-applications/
Anyway, I created my email template using an external service (https://topol.io/).
It is giving me errors when I try to use the generated HTML file with the String.FOrmat command referenced in the first link. I finally figured out it is this section of code causing the String.Format to fail.
This is my c# code that normally works with other HTML templates:
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
builder.HtmlBody = SourceReader.ReadToEnd();
}
string messagebody = string.Format(builder.HtmlBody,
//Not important
);
Now, this style code in the HTML causes the String.Format to crash (or the bodybuilder, I'm not sure exactly which one has the issue, it fails at 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]-->
Any ideas? I am open to suggestions of how to put this CSS section externally if the reason for the failure is not obvious.
You are getting that error because curly braces are used in string.Format
as a place holder for a value parameter.
One way to fix your problem is replacing braces with double braces:
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
);
You are calling String.Format
on a string that contains lots of CSS definitions. CSS definitions include many {
and }
pairs. String.Format
interprets {
and }
pairs as placeholders for substitution but, that is not what they represent in your string.
Why do you need to use String.Format
in this scenario?
Why not instead do,
builder.HtmlBody = File.ReadAllText(pathToFile);
If //Not important
is, in fact important, you could escape the braces in your template, as per this answer. So that braces you do not want to substitute become '{{'
and '}}'
respectively.
Basically, run a further one time preparation step on your template, switching {
for {{
and }
for }}
unless they represent a placeholder you would like to substitute.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With