重现Newtonsoft.Json程序集版本冲突

5
我已经开始尝试在Newtonsoft.Json中持续复现程序集版本冲突(与我之前的问题相关:为什么Newtonsoft.Json容易发生程序集版本冲突?),以便更好地理解它,但我无法触发它。
根据那里的最佳答案,如果我有一个引用Json.NET一个版本的项目A,然后它引用一个引用不同版本的项目B(并且它们没有程序集重定向来处理此问题),那么就应该发生这种情况。
我创建了一个包含类库项目和命令行项目的解决方案,两者都引用了Newtonsoft.Json,我使用Nuget Package Manager为两个项目安装了它,然后我编辑了类库packages.config文件以使用旧版本。
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net452" />

虽然命令行项目引用了最新的版本:

<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net452" />

这并不会引发问题,但项目仍然可以成功构建和执行(我只是将一个字符串序列化并从两个项目中打印它,然后从EXE调用DLL以确保它尝试加载Newtonsoft.Json的两个版本)。
如果需要的话,您可以在https://github.com/sashoalm/ReproduceNewtonsoftJsonBug上找到测试项目。
为什么问题没有被触发?

Newtonsoft引用中的 Specific Version 是否设置为 True 或 False ?http://docs.telerik.com/teststudio/img/troubleshooting-guide/visual-studio-tg/missing-assembly-references/fig3.png - mjwills
@mjwills,它已经设置为true了,我刚刚检查过。 - sashoalm
1个回答

6

首先,尽管 packages.json 文件中写着版本号是10,但你的控制台应用程序实际上引用的是版本6:

<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
  <HintPath>..\packages\Newtonsoft.Json.6.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>

然而,如果您解决了这个问题(例如通过卸载和重新安装包),它仍然能正常工作。这是因为在这种情况下存在自动绑定重定向,请参见此处:

从Visual Studio 2013开始,针对.NET Framework 4.5.1的新桌面应用程序使用自动绑定重定向。这意味着,如果两个组件引用了同一强名称程序集的不同版本,则运行时会自动将绑定重定向到输出应用程序配置(app.config)文件中较新的版本。

如果查看输出的ConsoleApp5.exe.config文件(不是Visual Studio中的app.config,而是Debug\Release文件夹中的),则会注意到绑定重定向已自动添加到其中:
<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

如果您删除它们然后运行目标 exe 文件,它将在运行时失败。
自动绑定重定向由 .csproj 文件中的一个属性控制。如果您打开控制台应用程序的 .csproj 文件,您将在其中一个 PropertyGroup 中看到:
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>

如果你将true改为false,你将禁用此功能,并且会看到你试图复制的警告信息。

哦,我找不到 bin\Debug 中的 app.config。只有 ConsoleApp5.exe.config 和 Newtonsoft.Json.xml,但它们没有提到 Newtonsoft.Json 的版本。 - sashoalm
是的,我的意思是 ConsoleApp5.exe.config - Evk
哦,好的。但是那个配置文件只有一个“<supportedRuntime>”键。如果你编译了它,会不同吗?也许我应该只是添加这些键。 - sashoalm
你解决了我在答案中提到的第一个问题吗?请检查你的 ConsoleApp5 .csproj 文件,确保你真正引用了 Newtonsoft.Json 的 10 版本,而不是像你从链接下载的原始项目中一样使用的 6 版本。虽然你已经安装了 nuget 包的 10 版本,但实际上仍在引用 6 版本。 - Evk
刚刚完成了,现在它可以工作了(或者更确切地说是不能工作——它抛出了异常)。谢谢!我已经将我的更改上传到了Github上——基本上我禁用了绑定重定向并按照你的建议更改了csproj文件。 - sashoalm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接