我正在尝试使用 C# 在 winforms 应用程序中生成 Gmail 草稿邮件。草稿消息需要采用 HTML 格式并且能够包含附件。
我能够使用 AE.Net.Mail
生成带有附件的草稿,但草稿消息是纯文本形式的(我不知道如何对 AE 进行编码)。 Net.Mail
给我一封 HTML Gmail 草稿邮件)。
为了将消息转换为 HTML 格式,我使用 MimeKit 获取 System.Net.Mail
消息并将其转换为 MimeMessage
消息。但是,我无法弄清楚如何按照 Gmail 草案规范的要求将 MIME 消息放入 RFC 2822 格式和 URL 安全的 base64 编码字符串中。
以下是 MimeKit 转换尝试的代码:
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
MailMessage msg = new MailMessage(); //System.Net.Mail
msg.IsBodyHtml = true;
msg.Subject = "HTML Email";
msg.Body = "<a href = 'http://www.yahoo.com/'>Enjoy Yahoo!</a>";
msg.Attachments.Add(file);
MimeMessage message = MimeMessage.CreateFromMailMessage(msg); //MimeKit conversion
//At this point I cannot figure out how to get the MIME message into
//an RFC 2822 formatted and URL-safe base64 encoded string
//as required by the Gmail draft specification
//See working code below for how this works in AE.Net.Mail
下面是使用 AE.Net.Mail
的代码,该代码可以运行,但会以纯文本形式生成 Gmail 草稿正文(基于 Jason Pettys 的 this article) ):
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
var msg = new AE.Net.Mail.MailMessage //msg created in plain text not HTML format
{
Body = "<a href = 'http://www.yahoo.com/'>Enjoy Yahoo!</a>"
};
var bytes = System.IO.File.ReadAllBytes(filePath);
AE.Net.Mail.Attachment file = new AE.Net.Mail.Attachment(bytes, @"application/pdf", FileName, true);
msg.Attachments.Add(file);
var msgStr = new StringWriter();
msg.Save(msgStr);
Message m = new Message();
m.Raw = Base64UrlEncode(msgStr.ToString());
Draft draft = new Draft(); //Gmail draft
draft.Message = m;
service.Users.Drafts.Create(draft, "me").Execute();
private static string Base64UrlEncode(string input)
{
var inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
// Special "url-safe" base64 encode.
return Convert.ToBase64String(inputBytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
}
有没有办法将 MimeKit 的 MimeMessage
消息转换为 RFC 2822 格式和 URL 安全的 base64 编码字符串,以便可以将其生成为 Gmail 草稿?如果做不到这一点,有没有办法在编码之前以 HTML 格式创建 AE.Net.Mail
消息?非常感谢所有帮助。
最佳答案
做你想做的事情的最简单方法是这样的:
static string Base64UrlEncode (MimeMessage message)
{
using (var stream = new MemoryStream ()) {
message.WriteTo (stream);
return Convert.ToBase64String (stream.GetBuffer (), 0, (int) stream.Length)
.Replace ('+', '-')
.Replace ('/', '_')
.Replace ("=", "");
}
}
但是更有效的方法需要实现我们自己的 UrlEncoderFilter 来替换您的“.Replace (...)”逻辑:
using MimeKit;
using MimeKit.IO;
using MimeKit.IO.Filters;
// ...
class UrlEncodeFilter : IMimeFilter
{
byte[] output = new byte[8192];
#region IMimeFilter implementation
public byte[] Filter (byte[] input, int startIndex, int length, out int outputIndex, out int outputLength)
{
if (output.Length < input.Length)
Array.Resize (ref output, input.Length);
int endIndex = startIndex + length;
outputLength = 0;
outputIndex = 0;
for (int index = startIndex; index < endIndex; index++) {
switch ((char) input[index]) {
case '\r': case '\n': case '=': break;
case '+': output[outputLength++] = (byte) '-'; break;
case '/': output[outputLength++] = (byte) '_'; break;
default: output[outputLength++] = input[index]; break;
}
}
return output;
}
public byte[] Flush (byte[] input, int startIndex, int length, out int outputIndex, out int outputLength)
{
return Filter (input, startIndex, length, out outputIndex, out outputLength);
}
public void Reset ()
{
}
#endregion
}
使用它的方式如下:
static string Base64UrlEncode (MimeMessage message)
{
using (var stream = new MemoryStream ()) {
using (var filtered = new FilteredStream (stream)) {
filtered.Add (EncoderFilter.Create (ContentEncoding.Base64));
filtered.Add (new UrlEncodeFilter ());
message.WriteTo (filtered);
filtered.Flush ();
}
return Encoding.ASCII.GetString (stream.GetBuffer (), 0, (int) stream.Length);
}
}
关于c# - 使用 MimeKit、C# Winforms 和 Google API 的 Gmail 草稿(带附件的 HTML),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35655019/