我对NewtonSoft有疑问。
我有一个包含3个项目的解决方案。项目A有项目B和项目C的参考点,项目B也有项目C的参考点.B和C都有NewtonSoft组装。 Project C具有获取JsonMediaTypeFormatter的功能:
new JsonMediaTypeFormatter()
该功能由所有三个项目调用。项目B和C都可以毫无问题地调用该功能。但是当项目A调用该函数时,它会抛出错误:
Method not found: 'Void Newtonsoft.Json.Serialization.DefaultContractResolver.set_IgnoreSerializableAttribute(Boolean)'
我注意到,即使项目A没有NewtonSoft引用,在构建项目时,Newtonsoft.json.dll也会复制到其bin \ Debug文件夹中。我想这是因为Newtonsoft程序集在项目B和C中都被设置为true for Copy Local optoin。如果我从Project A的bin \ Debug文件夹中手动删除这个dll,问题就解决了。
我的问题是为什么项目A可以命中异常,除了从项目A的bin \ Debug文件夹中手动删除Newtonsoft dll之外,还有其他解决办法吗?将Copy Local设置为false不是一个选项,因为它会阻止dll部署到项目B和C的自己的bin文件夹中。
任何建议都将不胜感激。
更新
这是我的代码段
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System.Net.Http.Formatting;
var jsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var dateConverter = new IsoDateTimeConverter
{
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
};
jsonSerializerSettings.Converters.Add(dateConverter);
var formatter = new JsonMediaTypeFormatter
{
//SerializerSettings = jsonSerializerSettings
};
如果我注释掉 SerializerSettings ,它可以正常工作。
如果我取消注释此行,应用程序将返回此类问题。
如果我只是将空白设置传递给它
var formatter = new JsonMediaTypeFormatter
{
//SerializerSettings = new JsonSerializerSettings{}
};
我收到了错误:
找不到方法:'Void System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.set_SerializerSettings(Newtonsoft.Json.JsonSerializerSettings)'
我认为它可能与项目内部的不同System.Net.Http.Formatting引用有关,但是我检查了引用设置,它们都指向文件
包\ Microsoft.AspNet.WebApi.Client.5.2.3 \ lib中\ net45 \ System.Net.Http.Formatting.dll
此代码驻留在项目C中。它仅在项目A调用时失败,项目B和C可以毫无问题地调用它。从Project A bin \ Debug文件夹中删除NewtonSoft.Json.dll后,它也适用于项目A调用。
你知道发生了什么事吗?如何检查项目中是否还有不同的参考版本冲突?谢谢,
答案 0 :(得分:3)
在这里,我终于解决了问题。
这个问题的原因在于,在项目A中,有一个参考库指向System.Net.Http.Formatting(5.2.3.0),它依赖于Newtonsoft Joson版本6.0.0.0。您可以在Assembly Explorer上进行检查。我最近将Newtonsoft更新到8.0.0.0,项目B和C引用了这个版本。构建项目时,Newtonsoft 8.0已根据项目B和C(Copy Local设置为true)复制到项目A的输出文件夹。当应用程序运行时,它将抛出错误
System.IO.FileLoadException : Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
或在我的调试模式下,它会抛出
{"The 'CreateJsonSerializer' method threw an exception when attempting to create a JSON serializer."}
<强>解决方案:强>
在项目A中添加app.config文件,包括下面的设置,将系统程序集绑定重定向到正确的NewtonSoft版本
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<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>
项目B可以成功调用项目C的原因是它在web.config文件中有这个重定向。
谢谢,
答案 1 :(得分:1)
我会以新方式&#34;来清理你做引用的方式。
除repositories.config和3 packages.config
外,您具有以下设置\SolutionFolder\
\SolutionFolder\MySolution.sln
\SolutionFolder\packages\
\SolutionFolder\packages\repositories.config
\SolutionFolder\CSProjectA\
\SolutionFolder\CSProjectA\CSProjectA.csproj
\SolutionFolder\CSProjectA\packages.config
\SolutionFolder\CSProjectB\
\SolutionFolder\CSProjectB\CSProjectB.csproj
\SolutionFolder\CSProjectB\packages.config
\SolutionFolder\CSProjectC\
\SolutionFolder\CSProjectC\CSProjectC.csproj
\SolutionFolder\CSProjectC\packages.config
每个packages.config都将如下所示
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
</packages>
repositories.config将如下所示
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\CSProjectA\packages.config" />
<repository path="..\CSProjectB\packages.config" />
<repository path="..\CSProjectC\packages.config" />
</repositories>
执行nuget恢复时,将创建以下内容
\SolutionFolder\packages\Newtonsoft.Json.4.5.11\
\SolutionFolder\packages\Newtonsoft.Json.4.5.11\lib\
\SolutionFolder\packages\Newtonsoft.Json.4.5.11\lib\net40\
\SolutionFolder\packages\Newtonsoft.Json.4.5.11\lib\net40\
\SolutionFolder\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll
\SolutionFolder\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.xml
所有.csproj引用(hintpath)都将是
..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll
这就是nuget为你做的事情(自动巫术 - 神奇地),但我在这里解释它。
这是你从参考文献中获得一致性的方法。
在你的本地方框中,你可以做一个正常的VS&#34; build&#34;或者&#34;重建&#34;。 如果您缺少软件包,可以使用此命令行调用(一次)修复它:
nuget.exe restore "\SolutionFolder\MySolution.sln"
构建(在构建服务器上)时,您将执行:
nuget.exe restore "\SolutionFolder\MySolution.sln"
msbuild.exe "\SolutionFolder\MySolution.sln"
APPEND
试试这个:
&#34;%WINDIR%\ Microsoft.NET \框架\ v4.0.30319 \ msbuild.exe&#34; &#34; MySolution.sln&#34; / p:Configuration = Debug; FavoriteFood = Popeyes /l:FileLogger,Microsoft.Build.Engine;logfile=MySolution.Debug.log &#34;%WINDIR%\ Microsoft.NET \框架\ v4.0.30319 \ msbuild.exe&#34; &#34; MySolution.sln&#34; / p:Configuration = Release; FavoriteFood = Popeyes /l:FileLogger,Microsoft.Build.Engine;logfile=MySolution.Release.log
查看日志以查看Newtonsoft.Json.dll的来源(最终在ProjectA \ bin \ Debug中)。
现在我回顾你的评论和OP,你确实有一个奇怪的问题。我想知道ProjectA \ bin \ Debug \ Newtonsoft.Json.dll是否可能来自其他来源。
答案 2 :(得分:0)
我有同样的问题。 项目A(Web应用程序)参考项目B(PCL),都具有相同的newtonsoft nuget包,并且A具有绑定重定向。 项目C(测试项目)参考项目B和E(也是PCL),都具有相同的newtonsoft nuget包。
当我构建项目A时,项目A工作正常。如果我构建(不是重建)项目C,项目E是构建a,项目B被跳过(alreadu构建)。但是项目A受到影响:有些东西用CL版本覆盖了bintons文件夹中的newtonsoft json DLL。现在项目A不会运行此方法未找到错误。
如果我在构建项目C之前手动替换项目A中的newtonsoft json dll与bin文件夹中的相同,那么A再次正常工作!
如果我然后开始调试项目C,则不会发生重建,但项目A停止工作!
我认为PCL版本和net45版本之间的newtonsoft json程序集有问题,而.NET引擎选错了。我已将net45版本添加到测试项目中,但没有成功。
更新------------
我找到的唯一解决方法是将2个解决方案中的项目分开并打开2个视觉工作室。 在解决方案A中,我添加项目A和B. 在解决方案B中,我添加了项目C及其依赖项B和E.
现在一切正常。项目A可以运行,运行/编译项目B不会干扰项目A.