Carga de archivos grandes mediante los SDK de Microsoft Graph

Varias entidades de Microsoft Graph admiten cargas de archivos reanudables para facilitar la carga de archivos grandes. En lugar de intentar cargar todo el archivo en una sola solicitud, el archivo se segmenta en partes más pequeñas y se usa una solicitud para cargar un único segmento. Para simplificar este proceso, los SDK de Microsoft Graph implementan una tarea de carga de archivos de gran tamaño que administra la carga de los segmentos.

Carga de un archivo grande en OneDrive

using var fileStream = File.OpenRead(filePath);

// Use properties to specify the conflict behavior
// using DriveUpload = Microsoft.Graph.Drives.Item.Items.Item.CreateUploadSession;
var uploadSessionRequestBody = new DriveUpload.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 myDrive = await graphClient.Me.Drive.GetAsync();
var uploadSession = await graphClient.Drives[myDrive?.Id]
    .Items["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 (ODataError ex)
{
    Console.WriteLine($"Error uploading: {ex.Error?.Message}");
}

Reanudación de una carga de archivos

Los SDK de Microsoft Graph admiten la reanudación de cargas en curso. Si la aplicación encuentra una interrupción de la conexión o un estado HTTP 5.x.x durante la carga, puede reanudar la carga.

await fileUploadTask.ResumeAsync(progress);

Carga de datos adjuntos grandes en el mensaje de Outlook

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

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

using var fileStream = File.OpenRead(filePath);
var largeAttachment = new AttachmentItem
{
    AttachmentType = AttachmentType.File,
    Name = Path.GetFileName(filePath),
    Size = fileStream.Length,
};

// using AttachmentUpload = Microsoft.Graph.Me.Messages.Item.Attachments.CreateUploadSession;
var uploadSessionRequestBody = new AttachmentUpload.CreateUploadSessionPostRequestBody
{
    AttachmentItem = largeAttachment,
};

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

// 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 (ODataError ex)
{
    Console.WriteLine($"Error uploading: {ex.Error?.Message}");
}