我在使用.net 4.7.2在Microsoft Graph Library 5中发送电子邮件时遇到大附件的麻烦.<



我的任务是将现有的电子邮件系统转移到使用Microsoft Graph。他们使用的是。net Framework 4.7.2。似乎绝大多数的例子都是。net 5及以上版本的,这给我正常的研究过程带来了一些问题。

应用程序发送邮件成功。我可以发送较小的附件作为文章的一部分,没有问题。问题在于大的附件。我可以让它上传附件但是,该电子邮件没有大的附件,尽管在帖子中有消息id,并且在上传结果中有成功状态。

疯狂的是,我可以让小附件发送大于3MB的东西,17MB是我尝试过的最大的。我所有的研究都表明这是不可能的,所以我遗漏了一些东西。

我认为大型附件问题是我在从。net 5+示例在线和我的。net 4.7.2客户端转换中做错的事情。

我已经设置了邮件的权限。读写和邮件发送。两者都是应用程序类型权限。

复制:

我的原型程序是使用。net 4.7.2的c# WinForms,带有一个按钮。为了消除尽可能多的假设,我将所有代码放入一个函数中,该函数由按钮的click事件触发。

我正在使用以下附加的using语句。

using Microsoft.Graph;
using Microsoft.Graph.Models;
using System.IO;
using Azure.Identity;

函数如下:

public async void SendEmailWithAttachments()
{
//Fill out tenantID, clientID, secret, objectID, path to a littleAttachment(<3MB) and bigAttachment(>3MB, <150MB)
//Add Email address as a string to EmailTo list.
string tenantID = "<insert tenant ID>";
string clientID = "<insert client ID>";
string secret = "<insert secret>";
string objectID = "<insert object id of the user and not the application>";
string EmailSubject = "Testing Email of Microsoft Graph Send Email with Attachments";
string EmailBody = "I really wish I could actually see the large attachments that I am uploading.";
List<string> EmailTo = new List<string>();
List<string> EmailCC = new List<string>();
List<string> EmailBCC = new List<string>();
FileInfo littleAttachment = new FileInfo(@"c:examplesmallfile.txt");
FileInfo bigAttachment = new FileInfo(@"c:exampleBigFile.jpg");
EmailTo.Add("YourEmail@exampleOfYourEmail.com");
var cred = new ClientSecretCredential(tenantID, clientID, secret, new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud });
GraphServiceClient graphClient = new GraphServiceClient(cred);
var requestBody = new Microsoft.Graph.Users.Item.SendMail.SendMailPostRequestBody();
// Create message
var draftMessage = new Microsoft.Graph.Models.Message
{
Subject = "Large attachment"
};
var savedDraft = await graphClient.Users[objectID].Messages.PostAsync(draftMessage);
requestBody.Message = savedDraft;
//var result2 = await graphClient.Users[objectID].Messages[savedDraft.Id].GetAsync();
requestBody.Message.ToRecipients = new List<Recipient>();
requestBody.Message.CcRecipients = new List<Recipient>();
requestBody.Message.BccRecipients = new List<Recipient>();
requestBody.Message.Subject = EmailSubject;
requestBody.Message.Body = new ItemBody
{
ContentType = Microsoft.Graph.Models.BodyType.Text,
Content = EmailBody
};
foreach (string to in EmailTo)
{
requestBody.Message.ToRecipients.Add(new Recipient { EmailAddress = new EmailAddress { Address = to } });
}
foreach (string to in EmailCC)
{
requestBody.Message.CcRecipients.Add(new Recipient { EmailAddress = new EmailAddress { Address = to } });
}
foreach (string to in EmailBCC)
{
requestBody.Message.CcRecipients.Add(new Recipient { EmailAddress = new EmailAddress { Address = to } });
}
//---------------------------------------------------Big Attachments-------------------------------------------------------
var fileStream = System.IO.File.OpenRead(bigAttachment.FullName);
var uploadRequestBody = new Microsoft.Graph.Users.Item.Messages.Item.Attachments.CreateUploadSession.CreateUploadSessionPostRequestBody
{
AttachmentItem = new AttachmentItem
{
AttachmentType = AttachmentType.File,
Name = bigAttachment.Name,
Size = fileStream.Length,
ContentType = "application/octet-stream"
}
};
var uploadSession = await graphClient.Users[objectID]
.Messages[requestBody.Message.Id]
.Attachments
.CreateUploadSession
.PostAsync(uploadRequestBody);
// Max slice size must be a multiple of 320 KiB
int maxSliceSize = 320 * 1024;
var fileUploadTask = new LargeFileUploadTask<FileAttachment>(uploadSession, fileStream, maxSliceSize);
var totalLength = fileStream.Length;
// Create a callback that is invoked after each slice is uploaded
IProgress<long> progress = new Progress<long>(prog =>
{
Console.WriteLine($"Uploaded {prog} bytes of {totalLength} bytes");
});
try
{
// Upload the file
var uploadResult = await fileUploadTask.UploadAsync(progress);
Console.WriteLine(uploadResult.UploadSucceeded ? "Upload complete" : "Upload failed");
}
catch (ServiceException ex)
{
Console.WriteLine($"Error uploading: {ex.ToString()}");
}
//--------------------------------------------------------Big Attachments Ends---------------------------------------------
//-----------------------------------------------------Little Attachment Works---------------------------------------------
byte[] littleStream = File.ReadAllBytes(littleAttachment.FullName);
requestBody.Message.Attachments = new List<Attachment>
{
new Attachment
{
OdataType = "#microsoft.graph.fileAttachment",
Name = littleAttachment.Name,
AdditionalData = new Dictionary<string, object>
{
{
"contentBytes", Convert.ToBase64String(littleStream)
}
}
}
};
//-----------------------------------------------------Little Attachment End-----------------------------------------------
requestBody.SaveToSentItems = false;
await graphClient.Users[objectID].SendMail.PostAsync(requestBody);
}

我试着从其他解决方案中改编答案,这些解决方案主要是在beta/旧的库版本中。似乎在微软图形库的第5版中,他们做了太多突破性的改变,无法真正适应这些例子。

虽然我能够适应,保存消息为草稿,保存小附件,保存大附件和发送消息,模式。

我去了Microsoft Graph网站,这是我编写弗兰肯斯坦代码的基础。当他们有c#可用时,我认为它只适用于。net 5及以上版本。一般来说,这些更改都需要某种包装器,但除了这个例子,它们基本上都是有效的。

Nothing似乎抛出错误。它就是发不出去。我的理解是,当附件上传时,它应该是附加的,因为我正在提供消息id。我想我是丢失了一些简单的东西,但我却不知所措。

你发布的代码中的逻辑看起来不正确,基本上你应该做的是

  1. 创建一个带有任何小附件的草稿并获得Id
  2. 使用步骤1中的Id创建上传会话
  3. 上传大附件
  4. 使用其发送邮件端点发送您创建的消息草稿

Users[objectID].Messages[draftMessage.Id].Send.PostAsync()

SendMail

await graphClient.Users[objectID].SendMail.PostAsync(requestBody);

只是从你在requestBody中的属性中创建一个新消息,你创建的草案消息的id(将在requestBody中)被忽略(你可以自己使用图形浏览器进行测试,你可以在id属性中放入垃圾,端点将忽略它,应该真的抛出一个错误IMO)。

还有

requestBody.SaveToSentItems = false;

这只适用于在没有草稿消息的单个操作中使用SendMail端点的情况。所以当你有大的附件并且需要使用Send Endpoint时,这将不起作用,没有其他选项,所以它将始终将消息保存到SentItems文件夹中,如果你不希望它在那里,你需要删除它。

例如一个简化的例子

public static void SendEmailWithAttachments(GraphServiceClient graphClient, string objectID, string recipient,FileInfo littleAttachment, FileInfo bigAttachment)
{
// Create message
var draftMessage = new Microsoft.Graph.Models.Message
{
Subject = "Large attachment test",               
};
draftMessage.ToRecipients = new List<Recipient>() { new Recipient() { EmailAddress = new EmailAddress() { Address = recipient } } };
//---------------------------------------------------Little Attachments-------------------------------------------------------
byte[] littleStream = File.ReadAllBytes(littleAttachment.FullName);
draftMessage.Attachments = new List<Attachment>
{
new Attachment
{
OdataType = "#microsoft.graph.fileAttachment",
Name = littleAttachment.Name,
AdditionalData = new Dictionary<string, object>
{
{
"contentBytes", Convert.ToBase64String(littleStream)
}
}
}
};
//---------------------------------------------------Little Attachments End---------------------------------------------------
var savedDraft = graphClient.Users[objectID].Messages.PostAsync(draftMessage).GetAwaiter().GetResult();
//---------------------------------------------------Big Attachments-------------------------------------------------------
var fileStream = System.IO.File.OpenRead(bigAttachment.FullName);
var uploadRequestBody = new Microsoft.Graph.Users.Item.Messages.Item.Attachments.CreateUploadSession.CreateUploadSessionPostRequestBody
{
AttachmentItem = new AttachmentItem
{
AttachmentType = AttachmentType.File,
Name = bigAttachment.Name,
Size = fileStream.Length,
ContentType = "application/octet-stream"
}
};
var uploadSession = graphClient.Users[objectID]
.Messages[savedDraft.Id]
.Attachments
.CreateUploadSession
.PostAsync(uploadRequestBody).GetAwaiter().GetResult();
// Max slice size must be a multiple of 320 KiB
int maxSliceSize = 320 * 1024;
var fileUploadTask = new LargeFileUploadTask<FileAttachment>(uploadSession, fileStream, maxSliceSize);
var totalLength = fileStream.Length;
// Create a callback that is invoked after each slice is uploaded
IProgress<long> progress = new Progress<long>(prog =>
{
Console.WriteLine($"Uploaded {prog} bytes of {totalLength} bytes");
});
try
{
// Upload the file
var uploadResult = fileUploadTask.UploadAsync(progress).GetAwaiter().GetResult();
Console.WriteLine(uploadResult.UploadSucceeded ? "Upload complete" : "Upload failed");
}
catch (ServiceException ex)
{
Console.WriteLine($"Error uploading: {ex.ToString()}");
}
//--------------------------------------------------------Big Attachments Ends---------------------------------------------
//send the Draft            
graphClient.Users[objectID].Messages[savedDraft.Id].Send.PostAsync().GetAwaiter().GetResult();
}

相关内容

  • 没有找到相关文章