编辑1:在进一步玩之后,似乎空间不是罪魁祸首,但可能是base64url编码方法。我提取了纯文本和 mime 消息的原始字符串,并在在线工具中进行了比较。在纯文本的情况下,它们都是相同的,但在 mime 消息的情况下,它们完全不同,但是如果我将它们解码回字符串,它们是相同的。我对编码解码知之甚少,因此将不胜感激。编辑结束。
我正在尝试使用 mimekit 在 c# 中撰写电子邮件并使用 google.apis.gmail.v1 发送。但它会抛出错误“需要收件人地址[400]。这是代码。
var mailMessage = new MailMessage
{
Subject = "test subject",
Body = " <h1>test body</h1>"
};
mailMessage.IsBodyHtml = true;
mailMessage.To.Add("testemail");
MimeMessage mm = MimeMessage.CreateFromMailMessage(mailMessage);
var gmailMessage = new Google.Apis.Gmail.v1.Data.Message
{
Raw = Base64UrlEncode(mm.ToString())
};
service.Users.Messages.Send(gmailMessage, "me").execute();
// Encoding method
public static string Base64UrlEncode(string text)
{
byte[] bytes = Encoding.UTF8.GetBytes(text);
return Convert.ToBase64String(bytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
}
上面的代码会抛出错误,但是如果我使用如下纯文本撰写电子邮件:
string plainText = "To:testemail\r\n" +
"Subject: test subject\r\n" +
"Content-Type: text/html; charset=us-ascii\r\n\r\n" +
"<h1>Test body<h1>";
如果我将此纯文本编码并将其传递给 gmail 消息的 Raw 属性,则它可以完美地工作。为了调试问题,我使用在线工具解码了纯文本和 mime 消息,我注意到的唯一区别是 To 标头值之前的空格,如下所示:
// plain text:
To:testemail
//mime message:
To: testemail
注意“To:”后面的空格。为了证实我的怀疑,我从 mime 消息中删除了空格并使用在线工具再次对其进行编码,并将编码的字符串传递给 Raw 属性,它可以正常工作。所以想出了一个hacky解决方案并尝试使用正则表达式删除空间,如下所示:
var corrected = Regex.Replace(mm.ToString(), @"To: ", "To:");
但由于某种原因,这不起作用,这对我来说没有意义。根据文档 Raw 属性采用 RFC 2822 格式和 base64url 编码的字符串,从我可以发现 RFC 2822 不允许在标头类型之后有空格。任何帮助将不胜感激:) 作为参考,这里的两个字符串都是从原始的一个作品解码的,而另一个则不是;
//plain text that works:
To:test@test.com
Subject: Test subject
Content-Type: text/html; charset=us-ascii
<h1>Test body <h1>
// mime message that throw error
To: test@test.com
Subject: test message
Date: Date
MIME-Version: 1.0
Content-Type: text/html; charset=us-ascii
<h1>test body</h1>