2016-11-29 44 views
1

我编写了一个C#WinForms应用程序,该应用程序使用Gmail API创建带附件的邮件草稿并将其上传到Gmail。这直到几个月前都运行良好。代码如下:Gmail API可恢复上传C#桌面应用程序草稿

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
Request payload size exceeds the limit: 1048576 bytes. [400]

我认为,谷歌改变了它的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编码的尝试。感谢您阅读这些。

+0

您最后一次尝试将@“message/rfc822”更改为GetMimeType(_uploadFile); – DaImTo

+0

欣赏@DaImTo的建议,但还是无法得到这个工作。 'stream.ReadTimeout'和'stream.WriteTimeout'的'System.InvalidOperationException'。我想知道这条河流与草案组是如何相互关联的。究竟应该流传什么,与草案中的内容有什么关系?这是否需要成为多部分MIME消息?有没有其他方法可以将上传声明为可恢复?将继续探讨这些和其他问题。 – joeschwa

+0

我不记得tbh我一直在挖掘图书馆的代码试图找出它:) – DaImTo

回答

1

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

从本质上讲,我所做的是

  1. 使用接受一个流对象作为参数的Create()方法的不同过载。
  2. 这个不同的重载是一个函数,它返回一个CreateMediaUpload类型。
  3. 此CreateMediaUpload类型具有上传(和上传异步)方法,支持隐藏下的可恢复上传,从而绕过原始邮件大小限制。

我发送的测试文件是1.6兆字节,远高于您(和我)以前收到的请求有效负载最大阈值。

Happy emailing!再次,让我知道如果你仍然有问题的评论...我也会在最后把调试/秒表/发送内容放到任何制作中去。它只是在那里进行测试。

 // 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("[email protected]"); 

     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)); 
     } 
+1

首先让我说声谢谢@HBomb!你的代码有效。只是想添加一件事。你的回答指出你重构了base64url编码,但你编写的代码忽略了它。正确的是,当我看到不需要编码时,我重读了[GMAIL API Working with Drafts页面](https://developers.google.com/gmail/api/guides/drafts)和[Gmail APi上传附件页面](https://developers.google.com/gmail/api/guides/uploads),并看到'CreateMediaUpload'上传二进制数据,而不是需要base64url编码字符串的标准草案创建。非常感激! – joeschwa

+0

@joeschwa - 不用担心,我更新了我的帖子,以反映编码被删除的事实。它存在于我以前版本的代码中,所以当我写这些代码的时候我有点困惑。感谢您指出!最好的,-H – HBomb