1

我正在尝试通过 Microsoft Graph 发送附件大于 4MB 的电子邮件。在网上搜索我得出的结论是,对于大于 4MB 的文件,我需要通过上传会话将文件上传到 onedrive,然后将其作为“参考附件”添加到电子邮件中。

到目前为止,我的代码如下所示,首先我将文件上传到一个驱动器

var graphClient = GetGraphClient();
var rootItem = graphClient.Users[userEmail].Drive.Root.Request().GetAsync().Result;
uploadSession = graphClient.Users[userEmail].Drive.Items[rootItem.Id].ItemWithPath(fullFileName).CreateUploadSession().Request().PostAsync().Result;

fullFileByteArray = Convert.FromBase64String(content);
stream = new MemoryStream(fullFileByteArray);

provider = new ChunkedUploadProvider(uploadSession, graphClient, stream);
driveItem = provider.UploadAsync(3).Result;

这工作得很好,我将文件上传到一个驱动器并获得所述文件的 ID。下一步是将电子邮件创建为草稿。

var email = await graphClient.Users[fromEmail].Messages.Request().AddAsync(message);

这也很好用,我将电子邮件创建为草稿(我可以在 Outlook 上看到它),并且我得到了所述附件的 ID。

现在到有问题的部分,当我尝试将附件添加到草稿电子邮件时。

foreach (var att in fileAttachments)
{
     var attachment = new ReferenceAttachment();
     attachment.Name = att.FullFileName;
     attachment.ContentType = att.MIMEType;
     attachment.Id = att.FileId;
     attachment.ODataType = "#microsoft.graph.referenceAttachment";
     attachment.Size = att.Size;
     attachmentsParsed.Add(attachment);

     await graphClient.Users[fromEmail].Messages[email.Id].Attachments.Request().AddAsync(attachment);
}

当我尝试执行 AddAsync() 它响应:

Message: The property 'SourceUrl' is required when creating the entity.
Inner error:
        AdditionalData:
        request-id: {{someId}}
        date: {{someDate}}
ClientRequestId: {{someId}}
) ---> Microsoft.Graph.ServiceException: Code: ErrorInvalidProperty
Message: The property 'SourceUrl' is required when creating the entity.
Inner error:
        AdditionalData:
        request-id: {{someId}}
        date: {{someDate}}
ClientRequestId: {{someId}}

问题是 ReferenceAttachment 没有 SourceUrl 属性,我也没有在上传文件的响应中找到 sourceUrl 参数。我尝试将它添加到附件的 AdditionalData 属性中,这是一个字典,但它不起作用。

还尝试像这样通过 Postman 发送请求(也尝试将其发送到 API 的 beta 版本):

{
    "name":"{{someName}}",
    "@odata.type": "#microsoft.graph.referenceAttachment",
    "sourceUrl": "{{someUrl}}",
    "contentType":"text/plain",
    "id":"{{someId}}",
    "size":"1553",
}

回应是

{
  "error": {
    "code": "ErrorInvalidProperty",
    "message": "The property 'SourceUrl' is required when creating the entity.",
    "innerError": {
      "request-id": "{{someId}}",
      "date": "{{someDate}}"
    }
  }
}

我在哪里添加这个 SourceUrl 属性,我从哪里得到它?

4

1 回答 1

0

我建议使用将大文件附件直接上传到消息,而不必先上传到 onedrive。这在下面的链接中进行了描述。 https://docs.microsoft.com/en-us/graph/outlook-large-attachments?tabs=http

现在,最新版本的 .Net SDK 以 LargeFileUploadTask 的形式支持此方案。

本质上,您需要执行以下步骤

  1. 为附件创建一个上传会话,如下所示。(请注意,目前在 beta 库中可用https://www.nuget.org/packages/Microsoft.Graph.Beta/0.10.0-preview
var fileStream; // file stream you wish to upload to the attachment

var attachmentItem = new AttachmentItem
{
    AttachmentType = AttachmentType.File,
    Name = "flower",
    Size = fileStream.Length
};

await graphClient.Me.Messages[email.Id].Attachments
    .CreateUploadSession(attachmentItem)
    .Request()
    .PostAsync();

  1. 使用您要上传的流创建任务。
// Create task
LargeFileUploadTask<FileAttachment> largeFileUploadTask = new LargeFileUploadTask<FileAttachment>(uploadSession, fileStream);
  1. (可选)您可以通过创建 IProgress 实例来设置对上传进度的监控
// Setup the progress monitoring
IProgress<long> progress = new Progress<long>(progress =>
{
    Console.WriteLine($"Uploaded {progress} bytes of {stream.Length} bytes");
});
  1. 将附件上传到邮件中!
UploadResult<DriveItem> uploadResult = null;
try
{
    uploadResult = await largeFileUploadTask.UploadAsync(progress);

    if (uploadResult.UploadSucceeded)
    {
        //File attachement uplaod only returns the location URI on successful upload
        Console.WriteLine($"File Uploaded {uploadResult.Location}");//Sucessful Upload
    }
}
catch (ServiceException e)
{
    Console.WriteLine(e.Message);
}

如果您查询邮件的附件,您现在应该可以毫无顾虑地查看您添加的附件

var attachements = await graphClient.Me.Messages[email.Id].Attachments.Request().GetAsync();
于 2019-12-16T09:24:44.250 回答