使用 Microsoft Graph SDK 上传大型文件

Microsoft Graph 中的许多实体支持 可恢复文件上传 ,以便更轻松地上传大型文件。 文件被切成较小的部分,并使用请求上传单个切片,而不是尝试在单个请求中上传整个文件。 为了简化此过程,Microsoft Graph SDK 实现了管理切片上传的大型文件上传任务。

将大文件上传到 OneDrive

using var fileStream = System.IO.File.OpenRead(filePath);

// Use properties to specify the conflict behavior
// in this case, replace
var uploadSessionRequestBody = new CreateUploadSessionPostRequestBody
{
    Item = new DriveItemUploadableProperties
    {
        AdditionalData = new Dictionary<string, object>
        {
            { "@microsoft.graph.conflictBehavior", "replace" }
        }
    }
};

// Create the upload session
// itemPath does not need to be a path to an existing item
var uploadSession = await graphClient.Drive.Root
    .ItemWithPath(itemPath)
    .CreateUploadSession
    .PostAsync(uploadSessionRequestBody);

// Max slice size must be a multiple of 320 KiB
int maxSliceSize = 320 * 1024;
var fileUploadTask = new LargeFileUploadTask<DriveItem>(uploadSession, fileStream, maxSliceSize, graphClient.RequestAdapter);

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, item ID: {uploadResult.ItemResponse.Id}" :
        "Upload failed");
}
catch (ServiceException ex)
{
    Console.WriteLine($"Error uploading: {ex.ToString()}");
}

恢复文件上传

Microsoft Graph SDK 支持 恢复正在进行的上传。 如果应用程序在上传过程中遇到连接中断或 5.x.x HTTP 状态,则可以继续上传。

fileUploadTask.ResumeAsync(progress);

将大型附件上传到 Outlook 邮件

// Create message
var draftMessage = new Message
{
    Subject = "Large attachment"
};

var savedDraft = await graphClient.Me
    .Messages
    .Request()
    .AddAsync(draftMessage);

using var fileStream = System.IO.File.OpenRead(filePath);
var largeAttachment = new AttachmentItem
{
    AttachmentType = AttachmentType.File,
    Name = "largefile.gif",
    Size = fileStream.Length
};

var uploadSession = await graphClient.Me
    .Messages[savedDraft.Id]
    .Attachments
    .CreateUploadSession(largeAttachment)
    .Request()
    .PostAsync();

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