ASP.NET 4.7 WebForms集成OWIN无法加载System.Runtime程序集如何解决
问题现象
运行接入Azure B2C OWIN中间件的ASP.NET 4.7 VB.NET WebForms应用时抛出异常:
未能加载文件或程序集“System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件。
绑定日志显示程序集加载时触发了版本重定向,将4.0.0.0版本的System.Runtime重定向到4.1.1.0后,在所有搜索路径均未找到对应文件,删除ASP.NET临时文件无法解决问题。
问题根因
该错误是安装OWIN中间件NuGet包时,依赖解析逻辑错误导致的:
安装高版本依赖包时自动拉取了面向.NET Standard的System.Net.Http.Primitives 4.2.29.0,该包依赖4.1.1.0版本的System.Runtime,NuGet自动生成的绑定重定向把.NET Framework内置的4.0.0.0版本System.Runtime引用错误重定向到了不存在的4.1.1.0版本——System.Runtime 4.1.1.0是.NET Core/.NET Standard专属版本,不会出现在.NET Framework 4.7的全局程序集缓存和项目输出目录中,因此触发加载失败。
分步修复操作
- 清理错误的绑定重定向配置
打开项目根目录的web.config,定位到<runtime>节点下的<assemblyBinding>段落,删除所有针对System.Runtime、System.Net.Http.Primitives的dependentAssembly重定向规则,尤其是将System.Runtime4.0.0.0版本重定向到4.1.1.0的条目必须完全移除。 - 移除不兼容的依赖包
打开NuGet包管理器控制台,依次执行以下命令,移除错误引入的跨版本依赖:
注意:.NET Framework 4.7已内置Uninstall-Package System.Net.Http.Primitives -Force Uninstall-Package System.Runtime -Force Install-Package System.Net.Http -Version 4.3.4System.Runtime程序集,永远不要手动安装名为System.Runtime的NuGet包,否则必然触发版本冲突。 - 统一OWIN包版本到兼容版本
高于4.2.2版本的OWIN相关包对.NET Framework 4.7的适配存在已知的依赖解析问题,执行以下命令将三个OWIN包统一降级到稳定兼容版本:Update-Package Microsoft.Owin.Security.OpenIdConnect -Version 4.2.2 Update-Package Microsoft.Owin.Security.Cookies -Version 4.2.2 Update-Package Microsoft.Owin.Host.SystemWeb -Version 4.2.2 - 彻底清理编译缓存
关闭所有Visual Studio窗口,手动删除以下路径的内容:- 项目根目录下的
bin、obj文件夹内所有文件 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files下所有和当前项目相关的文件夹- 本地IIS Express临时编译目录下的项目缓存
清理完成后重新打开Visual Studio,右键项目选择「重新生成」即可。
- 项目根目录下的
后续避坑提示
如果后续安装其他NuGet包时又自动生成了.NET Framework基础类库(比如System.Runtime、System.Collections、System.Linq等GAC内置库)的高版本绑定重定向,可以右键项目进入属性页,在「生成」分类下关闭「自动生成绑定重定向」选项,手动维护绑定规则即可,这类内置库的版本号统一保持为4.0.0.0即可,不需要重定向到更高版本。
内容的提问来源于stack exchange,提问作者David Shochet

