简体   繁体   English

ASP.NET CORE FILE上传问题

[英]ASP.NET CORE FILE upload issue

I have a file upload code that works for chrome but throws the following error for IE. 我有一个适用于chrome的文件上传代码,但对IE抛出以下错误。

"IOException: The process cannot access the file 'path\\filename' because it is being used by another process. System.IO.__Error.WinIOError(int errorCode, string maybeFullPath) System.IO.FileStream.Init(string path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, string msgPath, bool bFromProxy, bool useLongPath, bool checkHost) System.IO.FileStream..ctor(string path, FileMode mode, FileAccess access, FileShare share) System.IO.File.OpenWrite(string path) RES.Controllers.DataHandling.DataUploadController+d__5.MoveNext() in DataUploadController.cs + “ IOException:该进程无法访问文件'path \\ filename',因为它正在被另一个进程使用。 ,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共享)DataUploadController.cs中的System.IO.File.OpenWrite(字符串路径)RES.Controllers.DataHandling.DataUploadController + d__5.MoveNext()+

Controller action method below: 控制器动作方法如下:

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);

                    }
    }
}

View model below: 查看下面的模型:

 public class UploadedData
    {

        public IFormFile File { get; set; }
    }

I can imagine that there is nothing wrong with the code since it works for Chrome. 我可以想象代码没有问题,因为它适用于Chrome。 Does anyone have any idea what the problem is with IE? 有谁知道IE有什么问题吗?

This is due to different behaviours between Internet Explorer and Chrome. 这是由于Internet Explorer和Chrome之间的行为不同。 Chrome hides the path to the user directory for security reasons. 出于安全原因,Chrome隐藏了用户目录的路径。
This means you only get the filename in your variable (eg myfile.txt ). 这意味着您只能在变量中获取文件名(例如myfile.txt )。

While Internet Explorer gives you the full client path of the uploaded file ( C:\\Users\\User1\\myfile.txt ). Internet Explorer为您提供了上载文件的C:\\Users\\User1\\myfile.txt路径( C:\\Users\\User1\\myfile.txt )。

Path.Combine fails then and returns the client path (eg C:\\Users\\User1\\myfile.txt ) instead of the combined path to your upload directory. 然后, Path.Combine失败,并返回客户端路径(例如C:\\Users\\User1\\myfile.txt ),而不是上载目录的组合路径。

Your server can't open the file since in your test/dev environment the file is opened by your browser. 您的服务器无法打开文件,因为在您的测试/开发环境中,文件是由浏览器打开的。

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

having Path.GetFileName(..) around parsedContentDisposition.FileName fixes that problem. Path.GetFileName(..)周围使用Path.GetFileName(..) parsedContentDisposition.FileName解决此问题。

In short: 简而言之:

Path.Combine in IE tries to combine D:\\ , UploadedFiles and C:\\Users\\User1\\myfile.txt which results in C:\\Users\\User1\\myfile.txt and fails. IE中的Path.Combine尝试将D:\\UploadedFilesC:\\Users\\User1\\myfile.txt合并,导致C:\\Users\\User1\\myfile.txt失败。

Path.Combine in Chrome tries to combine D:\\ , UploadedFiles and myfile.txt which results in D:\\UploadedFiles\\myfile.txt and suceeds. Chrome中的Path.Combine尝试将D:\\UploadedFilesmyfile.txt组合在一起,从而导致D:\\UploadedFiles\\myfile.txt并出现顺序。

I think this behaviour is due to this security mechanism in Chrome and Firefox, discussed on this question on Stack Overflow . 我认为这种行为是由于Chrome和Firefox中的这种安全性机制所致, 在Stack Overflow对此问题进行了讨论。

Edit: Internet Explorer only uploads the full path on standard settings within the Local Intranet zone. 编辑: Internet Explorer仅在本地Intranet区域内的标准设置上上传完整路径。

I had this problem recently and found a solution. 我最近遇到这个问题,找到了解决方案。 This is my controller that recieves some data and some files from a form in a view. 这是我的控制器,它从视图中的表单接收一些数据和一些文件。 Basically it saves the files in a folder outside wwwRoot called "Documents". 基本上,它将文件保存在wwwRoot之外的文件夹中,称为“文档”。 It also overwrites files with the same name. 它还会覆盖具有相同名称的文件。 It's a very basic example so do some checks and error handling. 这是一个非常基本的示例,因此请执行一些检查和错误处理。 Do note that Edge will save the name of the file as the full pathname, so change the name after to accomodate that. 请注意,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;
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM