【发布时间】:2018-03-25 23:46:28
【问题描述】:
在 ASP.NET MVC 应用程序中,我通过 REST API 从 SharePoint Online 读取文件,并将其显示在 MVC 应用程序的当前浏览器窗口中。我有适用于较小文件的代码,但对于“大文件”(我不知道确切的断点)我得到一个OutOfMemoryException。这是控制器代码:
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);
}
我查看了 SO 和互联网,但找不到解决方案。
- 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
我开始通过方法WebClient.DownloadData 将所有数据读入byte[]。当我得到OutOfMemoryException 时,我认为通过方法WebClient.OpenRead 替换为Stream 会修复它,但我仍然遇到大文件的例外情况。对于较小的文件,行为正是我想要的。如何修复异常?
更新
上面的示例代码不是真正的代码。真正的代码有一个较低级别的客户端类检索流并将其向上传递到调用堆栈,最终传递给控制器。但是,客户端类确实使用了using 语句,如示例中所示。如果在方法返回时流关闭,并且代码退出 using 块,那么为什么它适用于较小的文件?此外,我实际上是通过使用缓冲区手动处理流并写入响应来使我的代码工作的。我当前的代码正在关闭finally 块中的流(在控制器操作方法中——仍然从较低级别的客户端类中检索流)。 (注意我回来发布我的新代码作为答案并关闭这个问题,但现在我有点困惑。)
【问题讨论】:
标签: asp.net-mvc