为什么 Gmail API 不会从 C# 以 HTML 格式发送电子邮件?

我正在尝试使用 Gmail API 从 C# 发送 HTML 电子邮件。电子邮件已发送,但 Gmail 拒绝承认它应该是 HTML 电子邮件。


这是我正在使用的代码:


var template = @"from: {1}{4}to: {0}{4}subject: {2}{4}MIME-Version: 1.0{4}Content-Type: text/html; charset=UTF-8{4}Content-Transfer-Encoding: base64{4}{4}{3}";

body = HttpUtility.HtmlEncode(body);

var result = string.Format(template, to, from, subject, body, "\r\n");

result = Convert.ToBase64String(Encoding.UTF8.GetBytes(result));


var gMessage = new Message()

{

    Raw = result

};

service.Users.Messages.Send(gMessage, "me").Execute();

这是在编码为 base64 之前结果字符串的样子:


from: test@test.com

to: test@test2.com

subject: testSubject

MIME-Version: 1.0

Content-Type: text/html; charset=UTF-8

Content-Transfer-Encoding: base64


<html><head>


<title>Push Email</title>   


</head>    

<body> blah  


</body></html>

(该应用程序实际上使用了真实的电子邮件地址,我在上面的示例中将其替换为“test@...”以保护隐私。)


我尝试了标题排列、内容传输编码(base64、7bit、8bit 等)、内容类型字符集(ascii、utf8 等)的所有可能组合,我尝试使用 UrlEncode 而不是 HtmlEncode,但电子邮件正文要么只是显示为未渲染的 HTML 或显示为编码的 url 字符串(取决于我是使用 html encode 还是 url encode 以及我指定的内容传输编码)。


关键是,邮件正在工作,正文正在发送,但它只是顽固地拒绝呈现 HTML。我要么得到这个:


<html><head> <title>Push Email</title> </head> <body> blah </body></html>

或这个:


%3chtml%3e%3chead%3e%0d%0a%0d%0a%3ctitle%3ePush+Email%3c%2ftitle%3e+++%0d%0a+%0d%0a%3c%2fhead%3e++++%0d%0a%3cbody%3e+blah++%0d%0a++++%0d%0a%3c%2fbody%3e%3c%2fhtml%3e

或这个:


&lt;html&gt;&lt;head&gt; &lt;title&gt;Push Email&lt;/title&gt; &lt;/head&gt; &lt;body&gt; blah &lt;/body&gt;&lt;/html&gt;

我只会发送一封 SMTP 电子邮件,但可能是出于安全考虑,如果您对帐户进行了 2 因素身份验证(我已经并且不打算禁用),Google 将不会允许它。


另外,我只是将 MIME 消息构建为常规字符串。这可能与它有关,但我不知道。我不打算使用任何第三方 nuget 包/库,例如 MimeKit。我只想要一个 C# 解决方案。


最后,我需要能够发送 HTML 电子邮件,以便我可以根据我的应用程序业务逻辑发送链接。


有什么建议吗?


月关宝盒
浏览 169回答 3
3回答

喵喵时光机

我终于明白了。首先,邮件正文不能被转义,但整个 MIME 字符串应该被转义。但是,如前所述,如果我让正文未编码,API 会抱怨无效的字节字符串。问题是生成的 base64 字符串应该以 URL 安全的方式进行编码。Gmail API 指南中的 python 代码使用了一个被调用的方法urlsafe_b64encode,它不同于普通的 base 64 方法,因为生成的字符串是 URL 安全的。我以为我可以使用 HTML 或 URL 编码在 C# 中复制它,然后使用标准Convert.ToBase64String方法将 MIME 字符串转换为 base64,但我错了。在搜索 MSDN 网站后,我终于找到了HttpServerUtility.UrlTokenEncode方法,该urlsafe_b64encode方法与python 方法所做的一样,即在 URL 安全变体中对字符串进行编码,并将其转换为 base64。最终代码就变成了:// Template for the MIME message string (with text/html content type)var template = @"from: {1}{4}to: {0}{4}subject: {2}{4}MIME-Version: 1.0{4}Content-Type: text/html; charset=UTF-8{4}Content-Transfer-Encoding: base64{4}{4}{3}";// Fill in MIME message fieldsvar result = string.Format(template, to, from, subject, body, "\r\n");// Get the bytes from the string and convert it to a URL safe base64 stringresult = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(result));// Instantiate a Gmail API message and assign it the encoded MIME messagevar gMessage = new Message(){&nbsp; &nbsp; Raw = result};// Use the Gmail API Service to send the emailservice.Users.Messages.Send(gMessage, "me").Execute();
打开App,查看更多内容
随时随地看视频慕课网APP