我正在编写一个类库(称为mylibrary.dll),它本身引用了更多的库 ->使用以下DLL(取自package.config进行版本概述):
<package id="EntityFramework" version="6.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net45" />
<package id="System.Data.SQLite" version="1.0.99.0" targetFramework="net45" />
<package id="System.Data.SQLite.Core" version="1.0.99.0" targetFramework="net45" />
<package id="System.Data.SQLite.EF6" version="1.0.99.0" targetFramework="net45" />
<package id="System.Data.SQLite.Linq" version="1.0.99.0" targetFramework="net45" />
<package id="UnmanagedExports" version="1.2.7" targetFramework="net45" />`
mylibrary.dll 是一个包装器,它向需要非托管代码的调用方公开一些托管代码(换句话说,需要本机 DLL 条目)。
如果我测试 myLibrary 的公共接口.dll通过 NUnit 测试方法根本没有错误。但是,如果我从目标应用程序通过相同的接口调用相同的方法.exe我认识到以下情况:
- 测试方法 A:调用简单的 JSON 到字符串操作(使用Newtonsoft.JSON 库)并且运行良好。
- 测试方法 B:调用执行后异步的方法,此外
var vResponseObject = await vResponse.Content.ReadAsAsync
>().ConfigureAwait(false);
在后台,ReadAsAsync 调用使用 Newtonsoft.JSON 对类型为 <T>
的对象进行反序列化。似乎这个函数是产生错误的函数:
无法加载文件或程序集"Newtonsoft.json,版本=6.0.0.0,区域性=中性,公钥令牌=............."或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。(HRESULT的例外:0x80131040)
HTTPContent.ReadAsAsync 由 Microsoft.AspNet.WebApi.Client (扩展 System.Net.Http) 提供,它本身依赖于 Newtonsoft.JSON 版本 6.0.x(请参阅此包的 NuGet 依赖项)。未安装 6.0.x 版,而是安装 8.0.x 版。因此,需要在 app.config 中管理的自动绑定重定向:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
</assemblyBinding>
现在我不知道如何解决这个问题。在我的项目中Microsoft.AspNet.WebApi.Client是唯一引用Newtonsoft.JSON(版本6.0.x,错误告诉我的版本)的其他库。似乎只是忽略了绑定重定向。因为它不是"找不到文件异常",所以我认为它能够找到 dll 的第 8 版,但预计为 6,对吧?所有 DLL 都与目标应用程序位于同一目录中.exe
使用部分解决方案进行更新:作为一种解决方法,我能够通过System.Net.Http.Formatting避免Newtonsoft.Json的外部调用.dll
//vResponseObject = await vResponse.Content.ReadAsAsync<ApiResponse<T>>().ConfigureAwait(false);
string vStr = await vResponse.Content.ReadAsStringAsync();
vResponseObject = JsonConvert.DeserializeObject<ApiResponse<T>>(vStr);
但是,如果我必须围绕像mydll这样的调用进行编码,那么这实际上不是有效的进一步开发解决方案>.dll>另一个第三方.dll
我刚刚使用7.0.1版解决了Newtonsoft的这个问题。 我替换了 web.config 文件中的旧绑定,这很奇怪:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
</dependentAssembly>
自:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
</assemblyBinding>
最后,将 Newtonsoft 引用从它指向的任何内容更改为 NuGet 包 v8 中的版本。 您最有可能指向许多Newton.Json DLL中的一个,即C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Stack 5\Packages\Newtonsoft.Json.6.0.3\libet40。 我不知道它为什么这样做,但我只对这个库有问题。
删除旧的引用并通过nuget获取新的dll,我认为这将解决大多数场景。
更改
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
为
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
并签入您的依赖项 Newtonsoft.Json。 如果它有黄色图标,请将其删除并手动添加。(确保添加 6.0 版本)。(您应该将 dll 放在项目文件夹或其他项目中)。如果这不起作用,请通过NuGet添加旧版本(我自己手动添加它们)。
dll 的位置通常是:C:\Users\Username\Documents\Visual Studio 2013\Projects\ProjectFolder\packages\Newtonsoft.Json.6.0.8\libet45(或任何版本的 .net)