找不到方法:'Void Newtonsoft.Json.Serialization.DefaultContractResolver.set_IgnoreSerializableAttribute(Boolean)'

时间:2016-05-04 14:56:33

标签: msbuild json.net system.net

我对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调用。

你知道发生了什么事吗?如何检查项目中是否还有不同的参考版本冲突?

谢谢,

3 个答案:

答案 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.