为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
月关宝盒 2021-10-24 16:39:49
我正在尝试使用 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.comto: test@test2.comsubject: testSubjectMIME-Version: 1.0Content-Type: text/html; charset=UTF-8Content-Transfer-Encoding: base64&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Push Email&amp;lt;/title&amp;gt;   &amp;lt;/head&amp;gt;    &amp;lt;body&amp;gt; blah  &amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;(该应用程序实际上使用了真实的电子邮件地址,我在上面的示例中将其替换为“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 电子邮件,以便我可以根据我的应用程序业务逻辑发送链接。有什么建议吗?
查看完整描述

3 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

我终于明白了。首先,邮件正文不能被转义,但整个 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 fields

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

// Get the bytes from the string and convert it to a URL safe base64 string

result = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(result));


// Instantiate a Gmail API message and assign it the encoded MIME message

var gMessage = new Message()

{

    Raw = result

};

// Use the Gmail API Service to send the email

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


查看完整回答
反对 回复 2021-10-24
  • 3 回答
  • 0 关注
  • 168 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信