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

Method not found: 'Void Newtonsoft.Json.Serialization.DefaultContractResolver.set_IgnoreSerializableAttribute(Boolean)'

我对 NewtonSoft 有疑问。

例如,我有一个包含 3 个项目的解决方案。项目 A 有项目 B 和项目 C 的参考点,项目 B 也有项目 C 的参考点。B 和 C 都有 NewtonSoft 程序集。项目 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 中都将 Copy Local optoin 设置为 true。如果我从项目 A 的 bin\Debug 文件夹中手动删除此 dll,问题就解决了。

我的问题是为什么项目A会出现异常,除了从项目A的bin\Debug文件夹中手动删除Newtonsoft dll之外有什么解决办法吗?将 Copy Local 设置为 false 不是一个选项,因为它也会阻止 dll 部署到项目 B 和 C 自己的 bin 文件夹中。

如有任何建议,我们将不胜感激。

更新

Here is my code snippet

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,它工作正常。

如果我取消注释这一行,应用程序将return这样的问题。

如果我只是将空白设置传递给它

var formatter = new JsonMediaTypeFormatter
{
    //SerializerSettings = new JsonSerializerSettings{}
};

我收到错误:

Method not found: 'Void System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.set_SerializerSettings(Newtonsoft.Json.JsonSerializerSettings)'

我认为可能与项目内部不同的System.Net.Http.Formatting引用有关,但我检查了引用设置,它们都指向文件

packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll

此代码驻留在项目C中,仅在项目A调用时失败,项目B和C可以毫无问题地调用它。一旦我从项目 A bin\Debug 文件夹中删除 NewtonSoft.Json.dll,它也适用于项目 A 调用。

你知道发生了什么事吗?以及如何检查项目中是否仍然存在不同参考版本冲突?

谢谢,

我会清理你做参考的方式......在 "new way".

您有以下设置,除了 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 引用(提示路径)都将是

..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll

这就是 nuget 为您所做的(自动巫毒魔术),但我在这里解释它。

这就是您从参考文献中获得一致性的方法。

在你的本地盒子上,你可以做一个普通的 VS "build" 或 "rebuild"。 如果你有丢失的包,你可以用这个命令行调用修复它(一次):

nuget.exe restore "\SolutionFolder\MySolution.sln"

构建时(在构建服务器上),您将执行:

nuget.exe restore "\SolutionFolder\MySolution.sln"

msbuild.exe "\SolutionFolder\MySolution.sln"

追加

试试这个:

"%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" "MySolution.sln" /p:Configuration=Debug;FavoriteFood=Popeyes /l:FileLogger,Microsoft.Build.Engine;日志文件=MySolution.Debug.log "%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" "MySolution.sln" /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 是否可能来自其他来源。

Here I finally got problem solved.

这个问题的原因是在项目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 复制到项目 A 的输出文件夹(Copy Local 设置为 true)。当应用程序为 运行 时,它会抛出错误

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 文件中有此重定向。

谢谢,

我也遇到了同样的问题。 项目 A(网络应用程序)参考项目 B(PCL),两者具有相同的 newtonsoft nuget 包,并且 A 具有绑定重定向。 项目 C(测试项目)参考项目 B 和 E(也是 PCL),它们都具有相同的 newtonsoft nuget 包。

当我构建项目 A 时,项目 A 工作正常。如果我构建(不重建)项目 C,则项目 E 是构建 a,d 项目 B 将被跳过(已构建)。但是项目 A 受到影响:某些东西用 CL 版本覆盖了其 bin 文件夹中的 newtonsoft json DLL。现在项目 A 不会 运行 出现此方法未找到错误。

如果我手动将项目 A 中的 newtonsoft json dll 替换为构建项目 C 之前 bin 文件夹中的同一个 dll,A 再次正常工作!

如果我然后开始调试项目 C,不会发生重建,但项目 A 停止工作!

我想 PCL 版本和 net45 版本之间的 newtonsoft json 程序集有问题,.NET 引擎选择了错误的版本。我在测试项目中添加了net45版本,没有成功。

更新------------

我发现的唯一解决方法是将项目分成 2 个解决方案并打开 2 个 visual studio。 在解决方案 A 中,我添加了项目 A 和 B。 在解决方案 B 中,我添加了项目 C 及其依赖项 B 和 E。

现在一切正常。项目A可以运行,项目B不干扰项目Arunning/compiling