调用.NET Framework 4.5编写的dll时报错无法加载System.Web.TraceContext如何解决
System.Web.TraceContext 是 .NET Framework 专属的 ASP.NET 运行时类型,.NET Core 3.1 运行时本身没有实现该类型,Microsoft.Windows.Compatibility 兼容包仅覆盖了 .NET Framework 中可迁移的通用 API,不包含 ASP.NET System.Web 下的专属类型,因此直接加载会触发类型加载失败。
方案1:添加程序集绑定重定向(零代码改动)
如果供应商 DLL 里的 TraceContext 相关代码仅为声明、实际运行时不会被执行到,你可以在 .NET Core 3.1 项目根目录新建/修改 app.config 文件,添加绑定重定向强制所有 System.Web 引用指向固定版本,绕过程序集加载校验:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
注意:如果运行时实际触发了 TraceContext 的调用逻辑,该方案仍会报错,仅适用于 TraceContext 相关逻辑为死代码的场景。
方案2:移除 DLL 中 TraceContext 无用依赖(极小代码改动)
因为你可以访问供应商 DLL 的代码,只需要全局检索所有引用 System.Web.TraceContext 的位置:
- 如果是仅用于诊断的 Trace 输出,直接替换为项目现有日志组件、或者注释掉相关逻辑即可,不需要修改其他业务代码
- 如果是作为方法参数传递但实际未使用,直接删除参数声明和引用即可
修改后重新编译 DLL 替换原有引用即可。
方案3:用 .NET Framework 代理进程调用(零 DLL 代码改动)
如果供应商 DLL 里的 TraceContext 逻辑是必须运行的业务逻辑,且完全不想改动 DLL 代码,你可以单独搭建一个基于 .NET Framework 4.5 的轻量进程(比如控制台程序、本地RPC服务),在该进程中加载运行供应商 DLL,你的 .NET Core 3.1 程序通过本地HTTP、命名管道的方式和代理进程通信,间接调用 DLL 的能力。
方案4:切换项目运行时为 .NET Framework(零 DLL 代码改动)
如果你的项目本身没有强依赖 .NET Core 3.1 的专属能力,直接把项目切换为基于 .NET Framework 4.8 运行,天然支持 System.Web 全量类型,不需要做任何代码改动。
内容的提问来源于stack exchange,提问作者Karl Ehlhardt

