msgraph-sdk-dotnet
msgraph-sdk-dotnet copied to clipboard
Cannot Download Very Large Attachments via Stream
My attachment processing server has limited memory, but lots of free disk. I can currently only access a File Attachment via the contentBytes property. This property is an array of bytes and is completely loaded in memory.
If the attachment is very large, it uses or exceeds all of my available memory. I would like to be able to access the attachment via stream so I can download it to disk without using all of my memory.
If not a Stream, perhaps a FileDownloadSession that provides parity to FileUploadSession.
Thanks for raising this @grippstick
Any chance you could share a code snippet of how you are trying to download the FileAttachment using the SDK?
Typically calls to endpoints returning streams have an extra HttpCompletionOption
parameter that may be used to avoid loading the entire response in memory by setting it to HttpCompletionOption.ResponseHeadersRead
as in the example below.
var photoContent = await graphClient.Me.Photo.Content
.Request()
.GetAsync(completionOption: HttpCompletionOption.ResponseHeadersRead);
I do not see a way to get a stream for Message Attachments. The code I am using is:
var attachment = await graphClient.Me
.Messages[msgId]
.Attachments[attachmentID]
.Request()
.GetAsync()
.ConfigureAwait(false) as FileAttachment;
Even if I wanted to get the entire MimeFile, I cannot provide the options needed to download efficiently.
var strm = await graphClient.Me.Messages[""].Content.Request().GetAsync().ConfigureAwait(false);
Hey @grippstick
I believe it should be possible to do this for the message contents.
var strm = await graphClient.Me.Messages["id"].Content.Request().GetAsync(completionOption: HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
as avaialable in the builder at https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/c26ebc00031c2f63c6527e9e6b0c376dbf95e782/src/Microsoft.Graph/Generated/requests/IMessageContentRequest.cs#L29
However, there is indeed an issue with the RequestBuilder for the attachement as it is missing a Content
segment.
For this you should be able to work around with as we fix the metadata to have this in the request builders by default
var attachmentRequestUrl = graphClient.Me.Messages[""].Attachments[""].AppendSegmentToRequestUrl("/content");
var attachmentRequest = new BaseRequest(attachmentRequestUrl, graphClient);
var streamResponse = await attachmentRequest.SendStreamRequestAsync(null,CancellationToken.None, completionOption: HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
Metadata issue fixed in v5 and is should be possible to do
var strm = await graphClient.Me.Messages["id"].Content.GetAsync();