HTML 在浏览器中看起来不错,但在电子邮件中却不行
HTML looks okay in browser but not in email
我在电子邮件编码方面遇到了一些问题。我正在从磁盘读取 HTML 文件并通过 Gmail 发送。当我在浏览器中打开 HTML 时,它看起来很棒。当我从 Visual Studio 复制 HTML 字符串并将其保存为 HTML 文件时,它看起来很棒。当我收到电子邮件时,它包含一堆无效字符。连列表项目符号都搞砸了!我确定这是编码问题,但文件编码为 UTF-8,在转换为 RAW 并通过 Gmail 发送之前看起来不错。
这是过程。我们使用 OpenXML SDK then we use the HtmlConverter 从 docx 中读取,将文档另存为 HTML。稍后 HTML 从文件中读入,转换为 RAW 格式并通过 GMail API 发送。
以下是一些相关的代码片段:
这是我们使用 HtmlConverter 保存 HTML 文件的地方。
HtmlConverterSettings settings = new HtmlConverterSettings()
{
AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }",
FabricateCssClasses = true,
RestrictToSupportedLanguages = false,
RestrictToSupportedNumberingFormats = false,
};
XElement htmlElement = HtmlConverter.ConvertToHtml( wdWordDocument, settings );
var html = new XDocument(
new XDocumentType( "html", null, null, null ),
htmlElement );
var htmlString = html.ToString( SaveOptions.DisableFormatting );
File.WriteAllText( destFileName.FullName, htmlString, Encoding.UTF8 );
这是我们读取存储的 HTMl 并将其转换为通过 Gmail 发送的地方。 (我们使用 Mimekit 进行转换。)
// Create the message using MimeKit/System.Net.Mail.MailMessage
MailMessage msg = new MailMessage();
msg.Subject = strEmailSubject; // Subject
msg.From = new MailAddress( strUserEmail ); // Sender
msg.To.Add( new MailAddress( row.email ) ); // Recipient
msg.BodyEncoding = Encoding.UTF8;
msg.IsBodyHtml = true;
// We need to loop through our HTML Document and replace the images with a CID so that they will display inline
var vHtmlDoc = new HtmlAgilityPack.HtmlDocument();
vHtmlDoc.Load( row.file ); // Read the body, from HTML file
...
msg.Body = vHtmlDoc.DocumentNode.OuterHtml;
// Convert our System.Net.Mail.MailMessage to RAW with Base64 encoding for Gmail
MimeMessage mimeMessage = MimeMessage.CreateFromMailMessage( msg );
Google.Apis.Gmail.v1.Data.Message message = new Google.Apis.Gmail.v1.Data.Message();
message.Raw = Base64UrlEncode( mimeMessage.ToString() );
var result = vGMailService.Users.Messages.Send( message, "me" ).Execute();
这就是我们的 base64 编码方式:
private static string Base64UrlEncode( string input )
{
var inputBytes = System.Text.Encoding.UTF8.GetBytes( input );
// Special "url-safe" base64 encode.
return Convert.ToBase64String( inputBytes )
.Replace( '+', '-' )
.Replace( '/', '_' )
.Replace( "=", "" );
}
电子邮件以 "Content-Type: multipart/mixed" 结尾,有两种选择。一个是
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
另一个是
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
纯文本和 HTML 都包含类似 =C3=A2=E2=82=AC=E2=84=A2 的字符串,而 HTML 部分包含 HTML header 其中包含奇怪的“3D”字符。
<meta charset=3D"UTF-8"><title></title><meta name=3D"Generator"=
content=3D"PowerTools for Open XML">
None 这种怪异现象出现在 HTML 之前转换为 Base64 并发送。
知道问题出在哪里吗?这与 UTF8 和 Mimekit 有什么关系吗?
你的问题的答案是:没有问题。这就是使用 quoted-printable
编码呈现 Raw 的简单方式。如果您发送和发送电子邮件并查看它的来源,Gmail 也是这样显示它的。
这是获取 "raw" 消息数据以便与 Google 的 API 一起使用的代码:
using (var stream = new MemoryStream ()) {
message.WriteTo (stream);
var buffer = stream.ToArray ();
var base64 = Convert.ToBase64String (buffer)
.Replace( '+', '-' )
.Replace( '/', '_' )
.Replace( "=", "" );
message.Raw = base64;
}
正如 brandon927 所指出的,text/html mime 部分的内容已经过引用打印编码。这是用于传输的 MIME 编码,以确保它适合 7 位 ascii 范围。
您需要对其进行解码才能获得原件 HTML。
对于 MimeKit,如果您使用 mimeMessage.HtmlBody
或将表示 text/html 部分的 MimeEntity
转换为 TextPart
并访问Text
属性.
我在电子邮件编码方面遇到了一些问题。我正在从磁盘读取 HTML 文件并通过 Gmail 发送。当我在浏览器中打开 HTML 时,它看起来很棒。当我从 Visual Studio 复制 HTML 字符串并将其保存为 HTML 文件时,它看起来很棒。当我收到电子邮件时,它包含一堆无效字符。连列表项目符号都搞砸了!我确定这是编码问题,但文件编码为 UTF-8,在转换为 RAW 并通过 Gmail 发送之前看起来不错。
这是过程。我们使用 OpenXML SDK then we use the HtmlConverter 从 docx 中读取,将文档另存为 HTML。稍后 HTML 从文件中读入,转换为 RAW 格式并通过 GMail API 发送。
以下是一些相关的代码片段:
这是我们使用 HtmlConverter 保存 HTML 文件的地方。
HtmlConverterSettings settings = new HtmlConverterSettings()
{
AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }",
FabricateCssClasses = true,
RestrictToSupportedLanguages = false,
RestrictToSupportedNumberingFormats = false,
};
XElement htmlElement = HtmlConverter.ConvertToHtml( wdWordDocument, settings );
var html = new XDocument(
new XDocumentType( "html", null, null, null ),
htmlElement );
var htmlString = html.ToString( SaveOptions.DisableFormatting );
File.WriteAllText( destFileName.FullName, htmlString, Encoding.UTF8 );
这是我们读取存储的 HTMl 并将其转换为通过 Gmail 发送的地方。 (我们使用 Mimekit 进行转换。)
// Create the message using MimeKit/System.Net.Mail.MailMessage
MailMessage msg = new MailMessage();
msg.Subject = strEmailSubject; // Subject
msg.From = new MailAddress( strUserEmail ); // Sender
msg.To.Add( new MailAddress( row.email ) ); // Recipient
msg.BodyEncoding = Encoding.UTF8;
msg.IsBodyHtml = true;
// We need to loop through our HTML Document and replace the images with a CID so that they will display inline
var vHtmlDoc = new HtmlAgilityPack.HtmlDocument();
vHtmlDoc.Load( row.file ); // Read the body, from HTML file
...
msg.Body = vHtmlDoc.DocumentNode.OuterHtml;
// Convert our System.Net.Mail.MailMessage to RAW with Base64 encoding for Gmail
MimeMessage mimeMessage = MimeMessage.CreateFromMailMessage( msg );
Google.Apis.Gmail.v1.Data.Message message = new Google.Apis.Gmail.v1.Data.Message();
message.Raw = Base64UrlEncode( mimeMessage.ToString() );
var result = vGMailService.Users.Messages.Send( message, "me" ).Execute();
这就是我们的 base64 编码方式:
private static string Base64UrlEncode( string input )
{
var inputBytes = System.Text.Encoding.UTF8.GetBytes( input );
// Special "url-safe" base64 encode.
return Convert.ToBase64String( inputBytes )
.Replace( '+', '-' )
.Replace( '/', '_' )
.Replace( "=", "" );
}
电子邮件以 "Content-Type: multipart/mixed" 结尾,有两种选择。一个是
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
另一个是
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
纯文本和 HTML 都包含类似 =C3=A2=E2=82=AC=E2=84=A2 的字符串,而 HTML 部分包含 HTML header 其中包含奇怪的“3D”字符。
<meta charset=3D"UTF-8"><title></title><meta name=3D"Generator"=
content=3D"PowerTools for Open XML">
None 这种怪异现象出现在 HTML 之前转换为 Base64 并发送。
知道问题出在哪里吗?这与 UTF8 和 Mimekit 有什么关系吗?
你的问题的答案是:没有问题。这就是使用 quoted-printable
编码呈现 Raw 的简单方式。如果您发送和发送电子邮件并查看它的来源,Gmail 也是这样显示它的。
这是获取 "raw" 消息数据以便与 Google 的 API 一起使用的代码:
using (var stream = new MemoryStream ()) {
message.WriteTo (stream);
var buffer = stream.ToArray ();
var base64 = Convert.ToBase64String (buffer)
.Replace( '+', '-' )
.Replace( '/', '_' )
.Replace( "=", "" );
message.Raw = base64;
}
正如 brandon927 所指出的,text/html mime 部分的内容已经过引用打印编码。这是用于传输的 MIME 编码,以确保它适合 7 位 ascii 范围。
您需要对其进行解码才能获得原件 HTML。
对于 MimeKit,如果您使用 mimeMessage.HtmlBody
或将表示 text/html 部分的 MimeEntity
转换为 TextPart
并访问Text
属性.