.NET Framework升级Newtonsoft.Json至13.0.1触发PostSharp报错咨询
- 现有基于.NET Framework的解决方案,使用PostSharp版本为
4.2.21.0 - 因业务要求需要将依赖的Newtonsoft.Json从
11.0.2升级至13.0.1,升级后构建失败,回退Newtonsoft.Json到11.0.2后构建恢复正常 - 构建时触发PostSharp未处理异常,异常堆栈如下:
Severity Code Description Project File Line Suppression State Error Unhandled exception (4.2.21.0, postsharp-net40-x86-srv.exe, CLR 4.0.30319.528449, Release): System.IndexOutOfRangeException: Index was outside the bounds of the array. at ^e9p3FN6izlJE.^TxMhIJ+U(^EyL1LQX01Ck8 _0) at PostSharp.Sdk.Binary.ModuleReader.ImportCustomAttributes() at PostSharp.Sdk.Binary.ModuleReader.ImportCustomAttributes(MetadataDeclaration _0) at PostSharp.Sdk.CodeModel.Collections.CustomAttributeDeclarationCollection.DoLazyLoading() at PostSharp.Sdk.CodeModel.Collections.ElementCollection`1.^7qsXyJec() at PostSharp.Sdk.CodeModel.Collections.ElementCollection`1.GetEnumerator() at PostSharp.Sdk.Extensibility.Tasks.AnnotationRepositoryTask.^H9TZo5Th(TypeDefDeclaration _0) at PostSharp.Sdk.Extensibility.Tasks.AnnotationRepositoryTask.^wwGmHrz+(IAnnotationInstance _0) at PostSharp.Sdk.Extensibility.Tasks.AnnotationRepositoryTask.Execute() at PostSharp.Sdk.Extensibility.Project.ExecutePhase(String phase) at PostSharp.Sdk.Extensibility.Project.Execute() at PostSharp.Hosting.PostSharpObject.ExecuteProjects() at PostSharp.Hosting.PostSharpObject.InvokeProject(ProjectInvocation projectInvocation).
按改造成本从低到高排序:
方案1:配置PostSharp跳过Newtonsoft.Json程序集扫描
改造成本最低,无需升级任何依赖。PostSharp 4.2默认会全量扫描所有引用程序集的自定义特性元数据,该版本的元数据解析逻辑不兼容Newtonsoft.Json 12+版本新增的特性结构,才会触发数组越界。在项目根目录新建或修改现有postsharp.config文件,添加排除Newtonsoft.Json的配置,让PostSharp不再读取该程序集的元数据即可:<?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.postsharp.org/1.0/configuration"> <Multicast> <ExcludeAssemblies>Newtonsoft.Json</ExcludeAssemblies> </Multicast> </Project>该方案仅适用于没有对Newtonsoft.Json中的类型应用PostSharp切面的场景,绝大多数常规业务项目都满足该条件。
方案2:升级PostSharp至兼容版本
PostSharp从6.0版本开始修复了新版程序集元数据解析的越界问题,原生兼容Newtonsoft.Json 13.x版本。如果项目允许升级PostSharp依赖,直接将PostSharp升级到6.0及以上的稳定版本即可正常构建,6.x版本依然完整支持.NET Framework项目,无需调整项目目标框架。方案3:多版本依赖隔离
若既无法升级PostSharp,也不能跳过Newtonsoft.Json的扫描,可以通过程序集加载隔离的方式让两个版本的Newtonsoft.Json共存:将PostSharp依赖的11.0.2版本存放到独立目录,业务代码正常引用13.0.1版本,通过配置运行时程序集解析逻辑,让PostSharp构建时加载兼容的旧版本,业务运行时加载新版本。该方案配置复杂度高,后续维护成本大,非特殊场景不推荐使用。
不要通过修改、重签名Newtonsoft.Json 13.0.1程序集的方式规避问题,该操作会破坏程序集完整性,极易引发运行时加载异常。
内容的提问来源于stack exchange,提问作者DuroForce

