Search code examples
c#microsoft-graph-apiconsole-applicationemail-attachments

How to upload attachment > 4mb with graph API with console application


I'm trying to upload a attachment > 4 mb to the draft that I created with graph API. Below are the codes that I have tried.

 var resultdraft = await graphServiceClient.Users["xxxxxxxxx.com"].Messages.PostAsync(message);

            var messageId = resultdraft.Id;


            var fileInfo = new FileInfo(@"D:\downloadFiles\dfdsfdsfdscd.txt");
            long fileSize = fileInfo.Length;


            using var fileStreamx = System.IO.File.OpenRead(@"D:\downloadFiles\dfdsfdsfdscd.txt");
            //var largeAttachment = new AttachmentItem
            //{
            //    AttachmentType = AttachmentType.File,
            //    Name = fileStream.Name,
            //    Size = fileStream.Length
            //};

            var requestBody = new Microsoft.Graph.Me.Messages.Item.Attachments.CreateUploadSession.CreateUploadSessionPostRequestBody
            {
                AttachmentItem = new AttachmentItem
                {
                    AttachmentType = AttachmentType.File,
                    Name = "flower",
                    Size = 3483322L,
                },
            };
            var result = await graphServiceClient.Users["xxxxxxxxxx.com"].Messages[messageId].Attachments.CreateUploadSession.PostAsync(requestBody);

I did managed to create a draft and have the message Id after the PostAsync(message).

I'm trying with the solution from https://learn.microsoft.com/en-us/graph/api/attachment-createuploadsession?view=graph-rest-1.0&tabs=csharp

But the solution did not work due to it's for delegated permission, Im running it with application permission within a c# console application. I know I probably have to change the requestBody type from the .Me to the Users["xxxxxxx.com"], but I cant find any resources that showing what should I change in order for this to work in a application permission environment.

Any help or guidance will be hugely appreciated. Thanks!


Solution

  • The class you need to use is Microsoft.Graph.Users.Item.Messages.Item.Attachments.CreateUploadSession.CreateUploadSessionPostRequestBody

    With the Kiota based SDK Intellisense is not that helpful if you put a using in eg

    using Microsoft.Graph.Users.Item.Messages.Item.Attachments;

    can help improve intellisense suggestions.

    Here's a working example I've used in the past

    eg

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