In a ASP.NET MVC app, I am reading a file from SharePoint Online via the REST API and displaying it in the current browser window for the MVC app. I have code that works for smaller files, but for "large files" (I don't know the exact breakpoint) I get an OutOfMemoryException
. Here's the controller code:
public ActionResult Index() {
System.IO.Stream stream = null;
string fileName = "whatever.ext";
string restUri = $"https://myhost.sharepoint.com/sites/mysite/_api/Web/GetFileByServerRelativePath('mypath/{fileName}')/openbinarystream";
string mimeType = MimeMapping.GetMimeMapping(fileName);
using (var webClient = new WebClient()) {
webClient.Credentials = myCredentials;
webClient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
var uri = new Uri(restUri);
stream = webClient.OpenRead(uri);
}
Response.AppendHeader("Content-Disposition", "inline; filename=" + fileName);
return File(stream, mimeType);
}
I have looked around SO and the internet, but I cannot find a solution.
- https://sharepoint.stackexchange.com/questions/186551/placing-a-sharepoint-openbinarystream-into-a-byte-array-csom
- OutOfMemoryException when I read 500MB FileStream
- OutOfMemoryException when send big file 500MB using FileStream ASPNET
I started out reading all the data into a byte[]
via method WebClient.DownloadData
. When I got the OutOfMemoryException
, I thought replacing with a Stream
, via method WebClient.OpenRead
, would fix it, but I'm still getting the exception for large files. For smaller files, the behavior is just as I want it. How can I fix the exception?
UPDATE
The example code above is not the real code. The real code has a lower level client class retrieves the stream and passes it up the call stack to, eventually, the controller. The client class does use a using
statement as shown in the example, though. If the stream is closed when the method returns, and the code exits the using
block, then why did it work for smaller files? Furthermore, I actually got my code working by processing the stream manually with a buffer and writing to the response. My current code is closing the stream in a finally
block (in the controller action method--still retrieving the stream from lower level client class). (Note I came back to post my new code as the answer and close this question, but now I'm a little confused.)