【问题标题】:Method not found: 'Void Newtonsoft.Json.Serialization.DefaultContractResolver.set_IgnoreSerializableAttribute(Boolean)'找不到方法:'无效 Newtonsoft.Json.Serialization.DefaultContractResolver.set_IgnoreSerializableAttribute(Boolean)'
【发布时间】:2016-05-04 14:56:33
【问题描述】:

我对 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 文件夹中。

任何建议都将不胜感激。

更新

这是我的代码 sn-p

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 引用有关,但我检查了引用设置,它们都是指向文件的

packages\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 调用中使用。

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

谢谢,

【问题讨论】:

  • 我刚刚更新了我上面的问题。谢谢

标签: msbuild json.net system.net


【解决方案1】:

到这里我终于解决了问题。

这个问题的原因是在项目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文件中有这个重定向。

谢谢,

【讨论】:

    【解决方案2】:

    我会清理你做引用的方式......以“新方式”。

    您有以下设置,除了 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“构建”或“重建”。 如果您缺少软件包,您可以使用以下命令行调用修复它(一次):

    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;logfile= 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 中)。

    现在我重新审视了您的 cmets 和 OP,您确实有一个奇怪的问题。我想知道 ProjectA\bin\Debug\Newtonsoft.Json.dll 是否可能来自其他来源。

    【讨论】:

    • 感谢您的帮助。我通常在 vs2015 中构建解决方案,选中“允许 NuGet 下载丢失的包”选项,我认为它会做与 nuget 还原相同的事情。我还在包文件夹中安装了 newtonsoft,在项目 B 和 C 中都安装了 .csproj 对它的引用。这不能阻止 build 将 newtonsoft 复制到项目 A 输出,从而导致发生此异常。但我很欣赏你的cmets。谢谢,
    • //quote "函数被所有三个项目调用。" //end-quote 因此 ProjectA 应该有一个对 Newtonsoft 的正确引用。如果 ProjectA 引用了 ProjectB 和/或 ProjectC,那么当然(并且正确地)/bin/Debug 或 bin/Release 目录将获得 Newtonsoft 的副本。
    • quote " 'Allow NuGet to download missing packages' " end-quote... 确保你阅读了这个docs.nuget.org/consume/package-restore/…你不想混合旧方式和新方式。
    • 我在答案中添加了“APPEND”。
    • 我刚刚更新了我上面的问题。谢谢@granadaCoder
    【解决方案3】:

    我也有同样的问题。 项目 A(Web 应用程序)参考项目 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 将不会运行此方法未找到错误。

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2016-09-29
      • 1970-01-01
      相关资源
      最近更新 更多