System.Text.Json反序列化错误System.MemoryExtensions无法加载System.Runtime.CompilerServices.Unsafe

System.Text.Json Deserialize Error System.MemoryExtensions Cannot Load System.Runtime.CompilerServices.Unsafe

类似于another question,但症状不同,我不想在问题中提出问题。

将 VS2017 与所有面向 .NET Framework 4.8 的项目一起使用。尝试了 System.Text.Json 的最旧 (4.6.0) 和最新 (5.0.2) 版本。还尝试针对 .NET Framework 4.6.1 中的所有项目。我构建了三个项目:

MyClassLib 函数在从 WinForms 应用程序调用时执行完美,但在从服务库调用时出现以下错误。失败的特定代码行:

Empl[] empls = JsonSerializer.Deserialize<Empl[]>(jsonString);

在 MyClassLib 内部,两个调用路径之间的一切完全相同。有什么区别?!?!

System.TypeInitializationException: The type initializer for 'System.Text.Json.JsonSerializer' threw an exception. ---> System.TypeInitializationException:   The type initializer for 'System.MemoryExtensions' threw an exception. ---> System.IO.FileLoadException:
      Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its
              dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)    at System.MemoryExtensions.MeasureStringAdjustment()    at System.MemoryExtensions..cctor()    --- End of inner exception stack trace ---    at System.MemoryExtensions.AsSpan(String text)    at System.Text.Json.JsonEncodedText.Encode(String value, JavaScriptEncoder encoder)    at System.Text.Json.JsonSerializer..cctor()    --- End of inner exception stack trace ---    at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)    at GlobAppSecLib.GlobAppSec.RetEmplSecurity(String EmplNetworkID, String AppName) in C:\[blah]\MyClassLibModule.cs:line 155

System.TypeInitializationException: The type initializer for 'System.Text.Json.JsonSerializer' threw an exception. ---> System.TypeInitializationException:   The type initializer for 'System.MemoryExtensions' threw an exception. ---> System.IO.FileLoadException:
      Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its
              dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)    at System.MemoryExtensions.MeasureStringAdjustment()    at System.MemoryExtensions..cctor()    --- End of inner exception stack trace ---    at System.MemoryExtensions.AsSpan(String text)    at System.Text.Json.JsonEncodedText.Encode(String value, JavaScriptEncoder encoder)    at System.Text.Json.JsonSerializer..cctor()    --- End of inner exception stack trace ---    at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)    at GlobAppSecLib.GlobAppSec.RetEmplSecurity(String EmplNetworkID, String AppName) in C:\[blah]\MyClassLibModule.cs:line 155

我注意到 System.Json.Text 拖拽的 DLL 是 'Product name' Microsoft .NET Core 和 Microsoft .NET Framework 的混合:

刚刚注意到 WinForms 客户端以 32 位运行,而 WcfSvcHost.exe 以 64 位运行。

构建 WinForms 服务主机而不是使用 WcfSvcHost.exe 是解决 'fixing' 问题的一种方法。 suggested by @sean-skelly included a link to the System.Runtime.CompilerServices.Unsafe NuGet package. Playing with that has made me conclude you can't get the 4.0.4.1 version of the dll to coexist with 5.0.2 version of System.Text.Json. Smells like a Microsoft screw up. Moved everything to VS 2019 and used latest versions, but to no avail. Part 2 of answer suggested by @sean-skelly led to an article about bindingRedirect 的第 1 部分似乎有点帮助。

正如几位评论者指出的那样,错误消息源于寻找一个版本的 dll 但找到了另一个版本。最终,答案是在一个或另一个配置文件中使用 bindingRedirect 条目。我最终将项目带到另一台机器上的 VS2019,并将 System.Text.Json 的 NuGet 包更新到最新的预览版本 (6.x)。当它在那里工作时,我将整个解决方案复制回我的机器 运行 VS2017。看起来该过程导致在几个配置文件中创建了一些 bindingRedirect 条目,如下所示。仍然没有答案的是为什么使用 System.Text.Json 5.02 的 MyClassLib.dll 和 MyServiceLib.dll 的原始版本分别在 WinForms 客户端和服务主机中工作得非常好,但是 MyServiceLib.dll 托管在 WcfSvcHost.exe 导致 MyClassLib.dll 中的错误消息。任何 .config 文件中都没有 bindingRedirect 条目,System.Memory.dll 和 System.Runtime.CompilerServices.Unsafe.dll 文件与 MyClassLib.dll 位于同一位置,并且版本完全相同。但有些事情不需要进一步调查,只要有解决方法。

MyClassLib.dll.config:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

MyServiceLib.dll.config:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
    </dependentAssembly>
    <dependentAssembly>
    <assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-5.0.0.1" newVersion="5.0.0.1" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>