.NET Core 6反射调用外部DLL时JObject参数传递失败排查
问题原因与解决方案
问题本质
这是程序集加载上下文隔离导致的类型标识冲突:虽然主程序和外部DLL中的参数都是Newtonsoft.Json.Linq.JObject,但CLR判定它们是不同类型,因此抛出看似矛盾的转换错误。
核心原因
- 版本/强签名不一致:主程序与外部DLL引用的
Newtonsoft.Json版本不同,或强签名(公钥令牌、哈希值)不匹配,CLR会将它们视为完全独立的程序集,对应的类型自然不兼容。 - 加载上下文隔离:如果外部DLL通过
Assembly.LoadFrom从自定义路径加载,会被放入「LoadFrom加载上下文」;而主程序的Newtonsoft.Json默认在「默认加载上下文」。两个上下文的程序集相互隔离,即使是同版本同文件的程序集,CLR也会视为不同实例,导致类型不匹配。
解决办法
1. 统一程序集版本与加载上下文
- 确保主项目和外部DLL项目通过NuGet安装完全相同版本的
Newtonsoft.Json包,且强签名配置一致(若启用)。 - 若外部DLL与主程序在同一目录,优先使用
Assembly.Load(assemblyName)而非Assembly.LoadFrom(path),让外部DLL加载到默认上下文,与主程序共享同一Newtonsoft.Json实例。
2. 配置程序集绑定重定向
如果必须用LoadFrom加载外部DLL,可在主程序的runtimeconfig.json中添加绑定重定向,强制CLR使用指定版本的Newtonsoft.Json:
{ "runtimeOptions": { "assemblyBinding": { "dependencies": [ { "name": "Newtonsoft.Json", "publicKeyToken": "30ad4fe6b2a6aeed", "version": "13.0.0.0", "culture": "neutral" } ] } } }
注意:将version替换为你实际使用的版本号
3. 类型兼容转换(兜底方案)
如果无法统一加载上下文,可通过JSON字符串中转:
- 主程序端将JObject序列化为字符串:
string jsonStr = myJsonData.ToString(Formatting.None); risultato = metodoInfo.Invoke(instanceDLL, new object[] { jsonStr }); - 外部DLL修改方法接收字符串参数,内部再反序列化为自身的JObject:
public Json_2fattori Test1_converter(string datijsonStr) { JObject datijson = JObject.Parse(datijsonStr); Json_2fattori mydati = new Json_2fattori { fattore1 = datijson["parametro1"].ToObject<double>(), fattore2 = datijson["parametro2"].ToObject<double>() }; return mydati; }
内容的提问来源于stack exchange,提问作者Nicola Agostoni
相关产品推荐
相关产品推荐

