Newtonsoft.Json 文件未找到异常仅在使用 "produce single file" 选项发布时

Newtonsoft.Json file not found exception only when published with "produce single file" option

绝对清楚,这不是数百万个类似错误的重复。

但是这个错误不是新出现的,包有问题。

这是我 30 年经验中遇到的最可怕的错误。

首先,我的应用程序使用 Newtonsoft.Json 包同时适用于调试和发布配置。

然后我使用 OneFile 和 ReadyToRun 选项发布它。

当我尝试 运行 时,我得到: System.IO.FileNotFoundException: 无法加载文件或程序集 'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'。

现在 - 程序包已链接到我的 exe 文件中。像其他 15 个有效的软件包一样。该机制甚至适用于 Windows 和 Linux 本机库。 我在依赖项中看到的包是版本 13.0.1.

这是当前版本。我的整个解决方案没有一个字符串“13.0.0”。对 Newtonsoft.Json 包的唯一引用是版本“13.0.1”。

但是当从我的单个文件构建启动时 - Newtonsoft.Json 决定抛出一个 FileNotFoundException.

我正在用头撞墙。 WTF正在进行中?很久很久以前,我在 .NET Framework 4.5 上遇到过类似的错误。我的新应用程序在 .NET 5.0 上运行。它没有奇怪的包版本重定向的东西。它只是将 nuget 用于包,它们都在我的项目文件中的一个地方定义。

这是 Newtonsoft.Json 或其他地方的错误吗?

显然,我不会在这里粘贴数百万行我的生产代码。代码很简单,在一个地方它做了类似 var x = new JObject() 的事情并抛出异常。

重现它的唯一方法是在 .NET 5.0 上创建一个新的 C# 项目,添加 Newtonsoft.Json 包引用,使用该包中的任何方法,然后发布它的 1 个文件并尝试 运行它。

我什至不确定它是否会触发其他计算机上的错误,因为上次我看到这个错误只发生在我的一台 Windows 服务器上,而不是其他机器上。

如果有人遇到此类问题,请按照以下方法解决问题:

我从我的解决方案中手动删除了所有 binobj 文件夹。 Clean solutionBatch build/Clean 没有帮助。

手动删除所有 binobj 文件夹并重建解决方案后,它可以正常工作。

错误在哪里?我不知道。它似乎是 Visual Studio 构建系统本身的错误。如果您发现类似的问题,也许这会为您节省几个小时。

为了让它更加清晰 - 我在代码中没有更改任何内容。我的代码中没有错误。从解决方案中删除所有“临时”文件夹后,它神奇地开始工作并且 FileNotFoundException 神奇地消失了。

顺便说一句,我猜到了发生了什么。我想 Newtonsoft 的工作方式与我相似,并且可能就像我们大多数发布 NuGet 软件包一样:我们完成了那些超级酷的新功能,扩展了 API,当然它们通过了我们所有的测试.所以我们发布版本“x.0.0”。然后突然之间,一些现实生活中的代码立即崩溃了!然后我们找到新的边缘案例添加到我们的测试和发布版本“x.0.1”。我们立即弃用包“x.0.0”。查看列出的 Newtonsof.Json 版本。看见? ;) 版本“x.0.0”寿命极短;)

我仍然不知道它是如何破坏 VS / .NET 构建系统的,但确实如此。发现这一点的人将立即成为 MVP。

现在无耻的外挂: https://github.com/HTD/Woof/tree/master/Tools/Nuke

一个工具,真正属于您的 Woof Toolkit 的一部分。这会破坏包缓存并删除程序启动目录下的所有 binobj 目录。所以 - 我将所有资源保存在 D:\Source 目录中。我把我的 nuke.exe 放在那里。当我在任何地方遇到行为不端的包裹时,我只是 运行 Nuke。然后任何 C# 程序的第一次构建都需要很长时间,但是包问题已经解决了。每一次。

当然可以用 shell 脚本替换它,但是因为我说 C# 比任何脚本语言都好...它没有依赖项,除了 .NET 6 你可能已经有了。

当您在 WPF 或 Blazor 应用程序中看到一百多个错误时,不要害怕。 .xaml.razor 文件需要重建 obj 目录。稍等片刻或手动构建项目。