适用于C#桌面应用程序草稿的Gmail API可恢复上传

时间:2016-11-29 23:50:02

标签: c# winforms gmail gmail-api

我编写了一个C#WinForms应用程序,该应用程序使用Gmail API创建带附件的邮件草稿并将其上传到Gmail。直到几个月前,这种方法运作良好。这是代码:

var service = new GmailService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = ApplicationName,
});

MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
Attachment file = new Attachment(FileLocation);
msg.Attachments.Add(file);

MimeMessage messageMIME = MimeMessage.CreateFromMailMessage(msg); //using MimeKit here

Google.Apis.Gmail.v1.Data.Message m = new Google.Apis.Gmail.v1.Data.Message();

m.Raw = Base64UrlEncode(messageMIME); //private method for Convert.ToBase64String
Draft draft = new Draft();
draft.Message = m;
service.Users.Drafts.Create(draft, "me").Execute();

以上代码现在仅在草稿邮件大小低于1 MB时才有效。当邮件/附件超出此限制时,代码现在会发出此错误:

  

Google.GoogleApiException:Google.Apis.Requests.RequestError
  请求有效负载大小超出限制:1048576字节。 [400]

我认为Google更改了API,因此现在需要使用resumable upload protocol上传附件超过1 MB的草稿。

现在上面代码片段中的最后一行有一个重载

service.Users.Drafts.Create(draft, "me", stream, @"message/rfc822");

enter image description here

使用CreateMediaUpload Class Reference,允许上传支持可恢复的上传协议。但是,无论我如何创建草稿体或编码流,我都无法正确使用此重载来创建和上传任何大小的草稿。构造我的代码的正确方法是什么,以便这个重载工作?或者是否有其他方法可以使用Gmail API中的可恢复上传协议从C#桌面应用上传带有附件的草稿消息?非常感谢所有帮助。

更新

如果我删除添加附件的两行代码,这行代码:

service.Users.Drafts.Create(draft, "me", stream, @"message/rfc822").Upload();

将在Gmail中创建包含正文的草稿。但是,我无法想到的任何内容都会使用此重载创建和/或流式传输草稿的附件。我尝试在附件中使用多部分MIME消息,文件流,内存流以及使用和不使用base64编码的尝试。感谢您阅读此内容。

1 个答案:

答案 0 :(得分:1)

我今天早上从未使用过C#中的Google Gmail API,所以我对你的问题很感兴趣。我复制了您的附件问题并使用下面的代码通过成功的测试电子邮件(包括附件)解决了这个问题,所以您应该好好去(如果是,请标记为已解决,或者如果您仍然遇到问题请在评论中告诉我我会再看看。)

基本上,我所做的是

  1. 使用Create()方法的不同重载,该方法将流对象作为参数。
  2. 这个不同的重载是一个函数,它返回一个CreateMediaUpload类型。
  3. 此CreateMediaUpload类型具有上载(和上载异步)方法,该方法支持可更改上传,从而绕过原始邮件大小限制。
  4. 我发送的测试文件是1.6兆字节,远高于你(和我)之前收到的请求有效负载最大阈值。

    发送电子邮件快乐!再次,如果你还有问题,请在评论中告诉我...在将其放入任何生产之前,我还要删除调试/秒表/发送内容。它就在那里进行测试。

           // Create Gmail API service.
            var service = new GmailService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = ApplicationName,
                });
    
    
            var file = new Attachment(FileLocation);
    
            MailMessage msg = new MailMessage();
            msg.IsBodyHtml = true;
            msg.Attachments.Add(file);
            msg.Body = "Tester Body";
            msg.To.Add("MyTestDestinationEmailAddress@Gmail.com");
    
            MimeMessage messageMIME = MimeMessage.CreateFromMailMessage(msg); //using MimeKit here
             MemoryStream memory = new MemoryStream();
            messageMIME.WriteTo(memory);
    
    
            Draft draft = new Draft();
    
            var createRequest = service.Users.Drafts.Create(draft, "me", memory, @"message/rfc822");
    
    
            var startTime = Stopwatch.StartNew();
            var uploadProgress = createRequest.Upload();
    
            if (uploadProgress.Status == UploadStatus.Completed)
            {
                Debug.WriteLine(String.Format("Elapsed Time: {0}", startTime.Elapsed));
                Debug.WriteLine(String.Format("Status: {0}", uploadProgress.Status.ToString()));
                Debug.WriteLine(String.Format("Bytes Sent: {0}", uploadProgress.BytesSent));
    
                //to send the draft email, uncomment the lines below
    
                //draft = createRequest.ResponseBody;
                //var send =  service.Users.Drafts.Send(draft, "me");
                //send.Execute();
    
            }
            else
            {
                Debug.WriteLine(String.Format("Exception: {0}", uploadProgress.Exception.Message));
            }