You need to enable JavaScript to run this app. .NET类库作插件调用时Newtonsoft.Json程序集加载失败如何解决
优惠活动
大模型
产品
解决方案
定价
更多

.NET类库作插件调用时Newtonsoft.Json程序集加载失败如何解决

问题根因定位

你遇到的"找不到指定程序集"报错,本质不是Newtonsoft.Json.dll文件物理缺失,而是.NET Framework的程序集绑定规则在插件宿主环境下不满足加载要求,和你本地清理引用、重配Nuget包的操作没有关系,核心触发原因有两类:

  • 探测路径匹配失败:.NET Framework默认只会从宿主程序exe的根目录做依赖探测,不会主动扫描插件所在的子目录,哪怕你把所有dll都完整放到插件目录,系统也找不到。
  • 强名称绑定校验不通过:编译时写入的程序集清单会记录引用的Newtonsoft.Json的AssemblyVersion(程序集版本号)和PublicKeyToken(公钥标记),哪怕磁盘上的dll文件版本是12.0.3.23909,只要它的实际程序集版本、公钥标记和清单记录不匹配,就会被判定为不符合加载要求,抛出“找不到程序集”的错误。

单独跑配套WinForm程序正常,是因为WinForm的基础探测路径就是自己的bin输出目录,Newtonsoft.Json和exe在同一路径下,完全满足探测和绑定要求,自然不会出错。

分步排查与解决

1. 先核对程序集的实际绑定标识

不要只看文件资源管理器属性里的版本号(那个是FileVersion文件版本,和.NET加载用的AssemblyVersion不是一回事),用PowerShell执行下面的命令,拿到真实的绑定标识:

# 查询你自己的插件dll记录的Newtonsoft.Json绑定要求
[System.Reflection.Assembly]::ReflectionOnlyLoadFrom("你的插件dll绝对路径").GetReferencedAssemblies() | Where-Object Name -eq "Newtonsoft.Json"
# 查询插件目录下存放的Newtonsoft.Json.dll的实际程序集版本、公钥标记
[System.Reflection.AssemblyName]::GetAssemblyName("插件目录下Newtonsoft.Json.dll的绝对路径")

重点核对两个值:

  • 插件清单记录的Newtonsoft.Json的AssemblyVersion、PublicKeyToken,和磁盘上dll的实际值是否完全一致
  • 第三方主程序根目录下如果已经存在Newtonsoft.Json.dll,同样查一下它的标识,看和你引用的是否匹配

小提示:官方Newtonsoft.Json从12.0.1版本开始,会把AssemblyVersion固定锁定为12.0.0.0,不管补丁版本升级到12.0.3、甚至13.0.3,程序集版本号都不会变,只是FileVersion会跟着更新,这也是你看到引用标识是12.0.0.0、实际文件版本是12.0.3.23909的原因,本身版本号是匹配的,问题大多出在探测路径上。

2. 验证探测路径问题

先把同版本的Newtonsoft.Json.dll直接复制到第三方主程序的exe所在根目录,重启主程序加载插件测试:

  • 如果报错消失,就确定是宿主的探测路径不覆盖插件子目录导致的加载失败
  • 这时候不要把dll长期放在宿主根目录,容易造成全局依赖版本冲突,最好的方案是在插件的入口初始化逻辑第一时间,挂载程序集加载拦截事件,手动处理Newtonsoft.Json的加载请求:
    // 在插件入口类的静态构造、或者入口方法的最开始执行
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
    {
        var requestedName = new AssemblyName(args.Name);
        // 匹配需要加载的Newtonsoft.Json组件
        if (requestedName.Name.Equals("Newtonsoft.Json", StringComparison.OrdinalIgnoreCase))
        {
            // 拼接插件目录下的Newtonsoft.Json.dll绝对路径
            var dllPath = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, 
                "插件所在的相对子目录", 
                "Newtonsoft.Json.dll");
            if (File.Exists(dllPath))
            {
                // 加载指定路径的dll
                return Assembly.LoadFrom(dllPath);
            }
        }
        // 其他程序集走默认加载逻辑
        return null;
    };
    
    注意:这个拦截事件必须在第一次调用Newtonsoft.Json的代码之前挂载,晚于加载时机的话,拦截逻辑不会生效。

3. 处理版本绑定冲突

如果查到宿主根目录已经存在其他版本的Newtonsoft.Json(比如宿主用的是11.x版本,程序集版本是11.0.0.0,公钥标记和你一致),直接在宿主根目录放12.x的dll会打乱宿主的原有依赖逻辑,这时候可以两个方案二选一:

  • 如果宿主的Newtonsoft.Json版本和你用的12.x完全兼容,直接删除插件目录下的Newtonsoft.Json.dll,复用宿主已经加载到内存的版本,减少重复加载开销
  • 如果版本不兼容,就用上面提到的AssemblyResolve拦截逻辑,把你插件目录下的12.x版本隔离加载,不影响宿主的原有组件加载。

4. 排查强名称不匹配问题

如果核对的时候发现磁盘上的Newtonsoft.Json.dll的PublicKeyToken和你插件清单记录的不一样,大概率是之前引用过非官方编译的无强名称签名的版本,直接从Nuget重新拉取官方的12.x版本替换,就可以解决公钥不匹配导致的加载失败问题。


内容的提问来源于stack exchange,提问作者rst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 06:54:06