2

C# を使用して winforms アプリケーションで Gmail の下書きメッセージを生成しようとしています。下書きメッセージは HTML 形式で、添付ファイルを含めることができる必要があります。

を使用して添付ファイル付きの下書きを生成できましたAE.Net.Mailが、下書きメッセージはプレーン テキストでした ( AE.Net.MailHTML Gmail の下書きメッセージを作成するためのコーディング方法がわかりませんでした)。

メッセージを HTML 形式に変換するために、MimeKit を使用してメッセージを取得し、System.Net.Mailそれをメッセージに変換しましたMimeMessage。ただし、MIME メッセージを RFC 2822 形式の URL セーフな base64 でエンコードされた文字列 (Gmail ドラフト仕様で要求されている) に変換する方法がわかりません。

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 によるこの記事に基づく)。

 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("=", "");
 }

MimeMessageGmail ドラフトとして生成できるように、MimeKit のメッセージを RFC 2822 形式の URL セーフな base64 エンコード文字列に変換する方法はありますか? AE.Net.Mailそれができない場合、メッセージをエンコードする前に HTML 形式でメッセージを作成する方法はありますか? すべてのヘルプは大歓迎です。

4

3 に答える 3

2

あなたが望むことをする最も簡単な方法は次のようなものです:

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);
    }
}
于 2016-02-27T01:03:28.567 に答える
0

それができない場合、AE.Net.Mail メッセージをエンコードする前に HTML 形式で作成する方法はありますか?

あなたが試すことができます

msg.ContentType = "text/html"; 

AE.Net.Mail.MailMessage で

于 2016-03-01T16:38:15.283 に答える