ASP.NET Core出现System.UnauthorizedAccessException错误:拒绝访问路径'C:\...'

4
我是一个新手在ASP.NET Core上,所以我正在尝试制作API。我正在尝试通过我的Web API上传图片。该图片将被保存到Web服务器上。我在运行API的Windows Server 2016标准版VPS机器上安装了IIS 10。当进行远程调试时,我收到如下错误信息:
{System.UnauthorizedAccessException: 访问路径"C:\HomeNET\Houses\13"被拒绝。 at System.IO.Win32FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, FileStream parent) at System.IO.Win32FileSystem.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, FileStream parent) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at System.IO.FileStream..ctor(String path, FileMode mode) at HomeNetAPI.Controllers.HouseController.d__6.MoveNext() in 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 有权修改该文件夹,但这也没有起作用。

5个回答

4
在我的情况下(IIS 8.5),我必须将 IIS_IUSRS 添加到应用程序文件夹中以解决此问题。

这真是救了我的一天。我一开始想用NetworkService用户,但当你选择使用应用程序池标识时,IIS_IUSRS才是正确的选择。 - yww325
给予写入和读取的权限,以便上传和下载都可以正常工作。 - Himalaya Garg

2

0

我在编写文件上传逻辑时遇到了错误,然后我看到了这篇帖子。不过,我是在 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);
                    }

获取传递数据的另一个选项是会话数据,但这个选项很方便,现在也能胜任工作。

问题中暗示需要一个单独的目录 - 这种类型的问题 - 是我发现需要将应用程序池的服务帐户赋予修改文件夹权限的安全问题。随着开发的变化,这可能会在以后出现。


0

0

为正在被服务使用的文件夹/文件提供 Network Service 权限

右键单击您的文件夹 -> 属性 -> 安全 -> 编辑 -> 添加 -> 类型:NETWORK SERVICE -> 选中完全控制允许复选框 -> 点击确定或应用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接