Newtonsoft.dll 13.0.1下WebClient.DownloadFile异常解决方案咨询
问题说明
项目使用13.0.1版本Newtonsoft.dll时,运行指定代码会触发异常;将Newtonsoft.dll降级至低版本可消除报错,但低版本存在使用限制:12.0.2版本Newtonsoft.dll存在已知安全漏洞,使用该版本时应用无法通过CodeQL安全扫描,会被标记漏洞风险,无法采用降级方案。
异常触发代码
using (WebClient webClient = new WebClient()) { webClient.DownloadFile(webResource, zipFilePath); // 该行代码触发错误 }
异常详情
System.Net.WebException: An exception occurred during a WebClient request. ---> System.IO.FileLoadException: Loading this assembly would produce a different grant set from other instances. (Exception from HRESULT: 0x80131401) at System.Net.WebClient.GetWebResponse(WebRequest request) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) at System.Net.WebClient.DownloadFile(Uri address, String fileName) --- End of inner exception stack trace --- at System.Net.WebClient.DownloadFile(Uri address, String fileName)
异常根因:HRESULT 0x80131401对应程序集授权集不匹配错误。Newtonsoft.Json 13.0.1版本默认标记了APTCA(允许部分受信任调用方)特性,在旧版.NET Framework沙箱、IIS经典模式、多版本程序集共存场景下,CLR会校验到不同加载上下文中的Newtonsoft程序集信任级别不一致,WebClient发起请求时触发底层程序集加载校验失败。
可行解决方案
- 替换
WebClient为HttpClient实现WebClient属于已被官方标记为不推荐使用的旧网络API,替换后不会触发Newtonsoft.Json 13.x相关的安全上下文加载冲突,是兼容性最高的修复方案。参考实现:
同步场景可直接使用同步方法获取响应内容写入文件即可。// 建议全局复用HttpClient实例,避免频繁创建导致端口耗尽 private static readonly HttpClient _httpClient = new HttpClient(); public async Task DownloadFileAsync(Uri webResource, string zipFilePath) { var fileBytes = await _httpClient.GetByteArrayAsync(webResource); await File.WriteAllBytesAsync(zipFilePath, fileBytes); } - 升级Newtonsoft.Json到无漏洞的修复版本
无需降级到存在安全漏洞的12.0.2版本,直接升级到13.0.2及以上正式稳定版即可。13.0.2版本修复了13.0.1中APTCA特性导致的部分信任场景加载冲突问题,同时不存在12.x版本的已知安全漏洞,可同时满足CodeQL安全扫描要求和运行兼容性要求。 - 配置运行时安全策略绕过校验
如果必须保留WebClient实现且暂时无法升级Newtonsoft.Json版本,可在项目的app.config/web.config中添加如下配置,关闭旧版CAS安全策略校验:
如果是IIS托管场景,需要将对应应用池的「加载用户配置文件」选项设置为<configuration> <runtime> <legacyCasPolicy enabled="false" /> <loadFromRemoteSources enabled="true" /> </runtime> </configuration>True,同时将托管管道模式调整为集成模式。 - 添加程序集绑定重定向统一加载版本
如果项目存在多个组件引用不同版本Newtonsoft.Json的情况,会导致同一进程内加载多个不同信任级别的Newtonsoft程序集触发校验失败,可通过绑定重定向强制所有组件统一加载指定版本的Newtonsoft.Json:<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.1.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
内容的提问来源于stack exchange,提问作者Hardik Parmar
相关产品推荐
相关产品推荐

