【问题标题】:ASP.NET Core System.UnauthorizedAccessException: Access to the path 'C:\..." is deniedASP.NET Core System.UnauthorizedAccessException:对路径“C:\...”的访问被拒绝
【发布时间】:2017-06-13 04:37:19
【问题描述】:

我是 ASP.NET Core 的新手,所以我正在制作 API。我正在尝试通过我的 Web API 上传图片。图片将被保存到网络服务器上。我在 Windows Server 2016 标准版 VPS 机器上运行 API。我在机器上安装了 IIS 10。我回来的错误(远程调试时):

{System.UnauthorizedAccessException:对路径“C:\HomeNET\Houses\13”的访问被拒绝。 在 System.IO.Win32FileStream..ctor(字符串路径、FileMode 模式、FileAccess 访问、FileShare 共享、Int32 bufferSize、FileOptions 选项、FileStream 父级) 在 System.IO.Win32FileSystem.Open(字符串 fullPath、FileMode 模式、FileAccess 访问、FileShare 共享、Int32 bufferSize、FileOptions 选项、FileStream 父级) 在 System.IO.FileStream.Init(字符串路径、FileMode 模式、FileAccess 访问、FileShare 共享、Int32 bufferSize、FileOptions 选项) 在 System.IO.FileStream..ctor(字符串路径,FileMode 模式) 在 HomeNetAPI.Controllers.HouseController.d__6.MoveNext() 在 C:\Users\okuhl\Documents\HomeNet\Web API\HomeNetAPI\src\HomeNetAPI\Controllers\HouseController.cs:line 83}

这很奇怪,因为创建了目录,但它们应该不存在。下面是一些失败发生的代码:

if (resultHouse != null)
{
    if (!Directory.Exists($"C:/HomeNET/Houses/{resultHouse.HouseID}"))
    {
        Directory.CreateDirectory($"C:/HomeNET/Houses/{resultHouse.HouseID}");
    }

    String fileName = new FileInfo(imageFile.FileName).Name;
    String fileExtension = new FileInfo(imageFile.FileName).Extension;
    using (var fileStream = new FileStream($"C:/HomeNET/Houses/{resultHouse.HouseID}", 
        FileMode.Create)) //Bombs out after this line
    {
        var result = imageFile.CopyToAsync(fileStream);
        if (result.IsCompleted)
        {
            newHouse.HouseImage = Path.Combine($"C:/HomeNET/Houses/{resultHouse.HouseID}", $".{fileExtension}");
            var updateResult = await Task.Run(() =>
            {
                return houseRepository.UpdateHouse(newHouse);
            });
            if (updateResult != null)
            {
                response.DidError = false;
                response.Message = $"House {newHouse.Name} has been created successfully! Invite friends ad family to your house!";
                response.Model = newHouse;
                return Ok(response);
            }
            else
            {
                response.DidError = true;
                response.Message = "Something went wrong with creating the house. Please try again";
                response.Model = newHouse;
                return BadRequest(response);
            }
        }
        else
        {
            response.DidError = true;
            response.Message = $"Something Went wrong with creating your house. House image could not be saved onto the system. \n {result.Exception.Message}";
            response.Model = newHouse;
            return BadRequest(response);
        }
    }
}

我已尝试让每个人都可以使用该文件夹,但没有成功。我还尝试授予我的 AppPool 修改文件夹的权限,但没有成功。

【问题讨论】:

    标签: c# asp.net-core asp.net-core-webapi


    【解决方案1】:

    就我而言(IIS 8.5),我必须将IIS_IUSRS 添加到应用程序文件夹才能解决此问题

    【讨论】:

    • 这可以节省我的时间。我在想 NetworkService 用户。但是 IIS_IUSRS 是一个(当您选择使用应用程序池标识时。
    • 同时授予写入和读取权限,因此上传和下载都可以工作。
    【解决方案2】:

    尝试检查正在运行应用程序池的用户(此处的说明:https://docs.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities)。

    如果该用户无权访问 C 盘,则写入将失败。

    (另外:尽量不要在代码中一次又一次地编写路径。将C:/HomeNET/Houses/ 声明为 const 并以这种方式引用它,或者更好的是,从 web.config 中读取它)

    【讨论】:

      【解决方案3】:

      您需要创建一个虚拟目录。以下是在 IIS 7 中的操作方法:https://technet.microsoft.com/en-us/library/cc771804(v=ws.10).aspx。对于 IIS 10,它可能类似。

      【讨论】:

        【解决方案4】:

        为服务正在使用的文件夹/文件提供网络服务权限

        右键单击您的文件夹 -> poperty 的 -> 安全性 -> 编辑 -> 添加 -> 输入 :NETWORK SERVICE -> 复选框完全控制允许 -> 按确定或应用

        【讨论】:

          【解决方案5】:

          我遇到了这篇文章,因为我在 FileUpload 逻辑上也遇到了错误。但是我在 IISExpress 下运行开发中的代码。我已经开始使用 IWebHostEnvironment 变量并将其分配给构造函数中的 Controller 类中的变量开始代码 - 然后读取一些让我认为它应该来自 Appdomain.CurrentDomain.BaseDirectory 的东西 - 这是我得到的根源错误 - BaseDirectory 信息的来源已经过时了 - 我去那里的错 - webHostEnvironment 确实是我需要的来源。

          我使用了 AppDomain.CurrentDomain.SetData("uploadDirName",path) - 这样我就可以在文件发布实际发生时将其拉回(会话状态想法)。那么使用这种方式后权限没有文件异常。

          path = Path.Combine(_webHostEnvironment.WebRootPath, "UploadedFiles");
                      if (!Directory.Exists(path))
                      {
                          Directory.CreateDirectory(path);
                      }
                      AppDomain.CurrentDomain.SetData("UploadPath", path);
          

          然后在 POST 逻辑中将其拉回

          path = Path.Combine(
                   AppDomain.CurrentDomain.GetData("UploadPath").ToString(), file.FileName); 
               using (var stream = new FileStream(path,
                              FileMode.Create))
                              {
                                  await file.CopyToAsync(stream);
                              }
          

          获取传递数据的另一个选项是 Session 数据 - 但这个选项很方便,并且现在可以工作。

          暗示问题中将需要一个单独的目录 - 这种类型的问题 - 是一个安全问题,我发现需要应用程序池的服务帐户必须被授予修改权限文件夹。这可能会随着时间的推移而发生变化。

          【讨论】:

            猜你喜欢
            • 2021-04-02
            • 2018-07-19
            • 2017-01-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-04-05
            相关资源
            最近更新 更多