如何在ASP.net MVC HttpPost中上传大文件

本文关键字:文件 HttpPost MVC ASP net | 更新日期: 2023-09-27 18:14:15

我尝试在ASP.net MVC中上传大文件,然后在DB中保存。但是当我这样做的时候,我有"outofmemoryexception"。我在这里发布我的文件:

[HttpPost]
        public void UploadAttachments(int docId, int folderId)
        {
            if (Request.Files.Count <= 0) return;  //throw exception?
            for (var i = 0; i < Request.Files.Count; i++)
            {
                try
                {
                    var file = Request.Files[i];
                    ProjectAttachmentInput attachment = new ProjectAttachmentInput();
                    attachment = SetAttachment(attachment, file, docId, folderId);
                    _documentationAppService.SaveUploadedFile(attachment);
                }
                catch { }
            }
        }

SetAttachment():

private ProjectAttachmentInput SetAttachment(ProjectAttachmentInput attachment, HttpPostedFileBase file, int docId, int folderId)
        {   
            attachment.FileName = file.FileName;
            attachment.FileContent = ReadFully(file.InputStream);
            attachment.ProjectAttachmentId = docId;
            attachment.ProjectAttachmentFolderId = folderId;
            return attachment;
        }

当我尝试ReadFully时,我得到OutOfMemoryException…

private static byte[] ReadFully(Stream input)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                input.CopyTo(ms);
                return ms.ToArray();
            }
        }

当我尝试输入时出现错误。我需要字节[]从文件和下一步保存在DB。如果文件小于100MB,则此操作有效。但是当我尝试200MB时,我有例外。

这段代码应该改变什么?

还有我的网。配置配置:

<system.webServer>
    <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="2147483648" />
    </requestFiltering>
  </security>
...
 <httpRuntime maxRequestLength="1073741824" targetFramework="4.5.1" />

如何在ASP.net MVC HttpPost中上传大文件

首先,如果你希望大文件上传到你的网站,你应该使用流IO,永远不要把整个文件加载到内存中。

第二,在我看来,在数据库中存储文件并不是一个很好的主意(即使使用FILESTREAM——再次强调,这是我个人的观点)。

有了这两点,我建议你这样做:

  1. 以内容可寻址的方式在文件系统中存储文件。这可以用纯流式IO来实现,并且文件大小不会成为问题(只要您的磁盘未满)
  2. 在你的数据库中,只保留文件哈希

"内容可寻址"部分意味着,本质上,每当您将文件保存到文件系统时,您首先计算该文件的哈希值,然后使用该哈希值作为文件名。这将使您的内容自动重复删除,您将不依赖于文件名。

发生这种情况是因为您试图将整个文件加载到内存中的数组中。这里的良好实践是使用流,而不是数组,并将文件作为BLOB一块一块地保存在数据库中(如果您真的希望将文件存储在DB中,这是一个有争议的选择)。

但是,为了将流保存为blob,您必须执行额外的步骤。

也许这篇文章可以帮助你(我不知道你使用的是哪种DB)

https://www.mssqltips.com/sqlservertip/1489/using-filestream-to-store-blobs-in-the-ntfs-file-system-in-sql-server-2008/