MVC FileContentResult-适用于DOC而非PDF
本文关键字:而非 PDF DOC 适用于 FileContentResult- MVC | 更新日期: 2023-09-27 18:21:45
我有以下ActionResult:
[Authorize]
public ActionResult DownloadFile(Guid id)
{
AdjusterFile file = (from f in db.AdjusterFiles
join a in db.Adjusters
on f.adjusterID equals a.id
join u in db.Users
on a.userID equals u.id
where u.username == HttpContext.User.Identity.Name
&& f.id == id
select f)
.FirstOrDefault();
return new FileContentResult(file.fileContent.ToArray(), file.fileContentType);
}
它非常适用于word文档(DOC/DOCX)。然而,每当我尝试下载通过相同过程上传的PDF时,它都会在Chrome中显示"加载PDF文档失败"。在IE中,它说:"文件已损坏,无法修复。"
内容类型为"application/pdf."
如何在MVC中下载PDF?
相关文件上传代码:
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
AdjusterFile newFile = new AdjusterFile();
newFile.id = Guid.NewGuid();
newFile.adjusterID = adj.id;
newFile.type = "eo";
newFile.fileName = file.FileName;
newFile.fileContent = array;
newFile.fileContentType = file.ContentType;
db.AdjusterFiles.InsertOnSubmit(newFile);
}
您不需要MemoryStream,可以这样尝试:
byte[] array = new byte[file.ContentLength];
file.InputStream.Read(array, 0, array.Length);
AdjusterFile newFile = new AdjusterFile();
newFile.id = Guid.NewGuid();
newFile.adjusterID = adj.id;
newFile.type = "eo";
newFile.fileName = file.FileName;
newFile.fileContent = array;
newFile.fileContentType = file.ContentType;
db.AdjusterFiles.InsertOnSubmit(newFile);
代码不起作用的原因在于MSDN文档中引用了您在MemoryStream上使用的GetBytes
方法:
请注意,缓冲区包含可能未使用的已分配字节。例如,如果字符串"test"被写入MemoryStream对象,从GetBuffer返回的缓冲区的长度是256,而不是4,其中252个字节未使用。要仅获取缓冲区中的数据,请使用ToArray方法;但是,ToArray在中创建数据的副本记忆力
因此,基本上,使用GetBytes方法,您可能不会总是获得写入流的确切字节数。或者,您可以使用ms.ToArray()
方法,该方法在您的场景中表现正确,但老实说,您根本不需要这个MemoryStream。您只是分配了一些不必要的空间,可以直接将上传文件的内容读取到字节数组中,如我的回答所示。
重要提示:我希望您意识到,通过将整个字节数组加载到内存中,Web服务器上的内存消耗可能会快速增长,尤其是当您开始处理大文件时。理想的解决方案是将文件存储在文件系统上,或者如果您使用的是MS SQL 2008或更高版本,请利用新的FILESTREAM类型。