ASP.NET CORE FILE上传问题

时间:2017-06-23 09:37:27

标签: c# asp.net asp.net-mvc google-chrome internet-explorer

我有一个适用于Chrome的文件上传代码,但会为IE引发以下错误。

  

“IOException:进程无法访问文件'path \ filename',因为它正由另一个进程使用。   System.IO .__ Error.WinIOError(int errorCode,string maybeFullPath)   System.IO.FileStream.Init(字符串路径,FileMode模式,FileAccess访问,int权限,bool useRights,FileShare共享,int bufferSize,FileOptions选项,SECURITY_ATTRIBUTES secAttrs,字符串msgPath,bool bFromProxy,bool useLongPath,bool checkHost)   System.IO.FileStream..ctor(字符串路径,FileMode模式,FileAccess访问,FileShare共享)   System.IO.File.OpenWrite(字符串路径)   DataUploadController.cs中的RES.Controllers.DataHandling.DataUploadController + d__5.MoveNext()   +

以下控制器操作方法:

public async Task<IActionResult> Upload(UploadedData data)
        {
   var filename=string.Empty;
      if (ModelState.IsValid)
                {
                    var file = data.File;

                    var parsedContentDisposition =
                        ContentDispositionHeaderValue.Parse(file.ContentDisposition);
                     filename = Path.Combine(_hostingEnvironment.ContentRootPath,
                        "UplaodedFiles", parsedContentDisposition.FileName.Trim('"'));


                    using (var stream = System.IO.File.OpenWrite(filename))
                    {
                        await file.CopyToAsync(stream);

                    }
    }
}

查看以下模型:

 public class UploadedData
    {

        public IFormFile File { get; set; }
    }

我可以想象代码没有任何问题,因为它适用于Chrome。有谁知道IE的问题是什么?

2 个答案:

答案 0 :(得分:4)

这是由于Internet Explorer和Chrome之间的行为不同。 出于安全原因,Chrome会隐藏用户目录的路径 这意味着您只能在变量中获取文件名(例如myfile.txt)。

Internet Explorer为您提供上传文件的完整客户端路径(C:\Users\User1\myfile.txt)。

Path.Combine失败,然后返回客户端路径(例如C:\Users\User1\myfile.txt),而不是上传目录的组合路径。

您的服务器无法打开该文件,因为在您的测试/开发环境中,您的浏览器会打开该文件。

filename = Path.Combine(@"D:\",
               "UploadedFiles", Path.GetFileName(parsedContentDisposition.FileName.Trim('"')));

Path.GetFileName(..)周围parsedContentDisposition.FileName解决了这个问题。

简而言之:

IE中的

Path.Combine尝试合并D:\UploadedFilesC:\Users\User1\myfile.txt,这会导致C:\Users\User1\myfile.txt并失败。

Chrome中的

Path.Combine会尝试合并D:\UploadedFilesmyfile.txt,从而导致D:\UploadedFiles\myfile.txt并成功。

我认为这种行为是由于Chrome和Firefox中的这种安全机制,在this question on Stack Overflow上进行了讨论。

修改 Internet Explorer仅上载本地Intranet区域内标准设置的完整路径。

答案 1 :(得分:0)

我最近遇到了这个问题并找到了解决方案。这是我的控制器,它从视图中的表单中获取一些数据和一些文件。基本上它将文件保存在wwwRoot之外的文件夹中,名为&#34; Documents&#34;。它还会覆盖具有相同名称的文件。这是一个非常基本的例子,所以做一些检查和错误处理。 请注意,Edge会将文件名保存为完整路径名,因此请在更改后再更改名称。

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SaveDocument(IList<IFormFile> files, 
HomeViewModel model)
{            
   foreach (IFormFile file in files)
    {
       string name =   
       ContentDispositionHeaderValue.Parse(file.ContentDisposition)
       .FileName.Trim('"');

       var filename = this.EnsureCorrectFilename(name);
       using (FileStream output = System.IO.File.Create(this.GetPathAndFilename(filename)))
                await source.CopyToAsync(output);

    }

        //...maybe save to db and return somewhere
}

private string EnsureCorrectFilename(string filename)
   {
        if (filename.Contains("\\"))
            filename = filename.Substring(filename.LastIndexOf("\\") + 1);

        return filename;
   }

private string GetPathAndFilename(string filename)
   {           
        return _env.ContentRootPath + "\\Documents\\" + filename;
   }