程序发布服务器IIS 请求带文件流的API出现异常 System.UnauthorizedAccessException: Access to the path 'C:\Windows\TEMP\ASPNETCORE_5641d7f8-09a6-41c8-99e9-bae2dd5268bb.tmp' is denied.
背景:
程序发布服务器IIS,请求带文件流参数的API<FormData>出现异常
此API在本地调试和发布本地IIS都未出现此异常
且程序中未明确使用过“'C:\Windows\TEMP...”此目录
原因:
虽然程序中未明确使用这个路径,但 ASP.NET Core / IIS 自己在用。
ASP.NET Core 的 Data Protection、调试符号生成、日志缓冲、文件上传中间件、运行时编译(Razor) 等组件,默认都把 C:\Windows\Temp 当成最后一级后备目录。
当进程标识 ApplicationPoolIdentity 对 C:\Windows\Temp 没有 Write 权限时,就会在你第一次触发这些功能时抛出 UnauthorizedAccessException,看起来就像“我明明没碰这个路径
文件上传的过程:当文件上传时就会将IFormFile的缓冲区数据写在C:\Windows\Temp,后才会将IFileForm的缓冲区数据写入到程序指定的文件目录
当文件的大小超过64k时文件会存在环境变量为%ASPNETCORE%指定的路径,若环境变量不存在则会存在系统的默认缓存路径下“C:\Windows\Temp”。
当文件大小不超过64k时会存在内存中
解决:
从程序池解决
1.程序池=》高级配置=》加载用户配置文件=》设置值为True
2.更改程序池标识,更改标识为非“ApplicationPoolIdentity”
内置账户选择非“ApplicationPoolIdentity”
或者选择定义账号,设定义一个自定义账户
3.程序中手动指定程序的临时目录
在程序入口Program.cs的顶部写入以下代码指定临时目录
var myTemp = Path.Combine(AppContext.BaseDirectory, @"Temp"); Directory.CreateDirectory(myTemp); Environment.SetEnvironmentVariable("TMP", myTemp); Environment.SetEnvironmentVariable("TEMP", myTemp);
4.给程序池赋予权限,此方法只能临时救急-仅限开发环境
IIS → 应用池 → 高级设置 → 进程模型 → 标识 记下名字
资源管理器=》在到目录“C:\Windows\TEMP”下 右键属性=》安全=》编辑=》添加=》
IIS AppPool\<你的池名>
选择“检查名称“,回去程序池中找对应的池名,存在如下
不存在给出提示
最后点击“确定”即可