.Net Standard 4.7.1无法在序列化期间加载System.Private.CoreLib

时间:2018-05-05 14:34:41

标签: c# .net .net-standard akka.net

我正在努力将我的大部分项目迁移到.Net Standard 2.0。

.net标准4.7.1中项目的最后一部分是WCF前端。 此可执行文件通过ClientServiceReceptionist通过库Akka.net与.net核心应用程序进行通信。

akka.net工作之间的网络通信。 除非它尝试序列化ReadOnlyCollection。

在这种情况下,系统会尝试加载" System.Private.CoreLib.dll"那是不可用的。

enter image description here

我使用.net标准2.0库来解决.net 4.6的许多问题,这些库必须在4.7.1中得到纠正。我从package.config传递给PackageReference。

我尝试使用NewtonSoft作为序列化程序代替Hyperion而没有进展。

有没有人有想法,解决方案?

编辑:07-05-2018

enter image description here

当我通过ClusterClientReceptionist发送一个ClusterClient.Send对象时,问题就在于WCF入口点。

发送的对象仅包含boolean,string,Guid和字符串属性数组。

编辑08-05-2018

发送的对象如下所示:

J

使用构造函数构建hierachi中使用的每个对象。 所有属性都是只读的。

我尝试在WCF部分发送之前对结果进行序列化和反序列化,然后才能正常工作。

{
  (string) "Path": "/user/ProcessOrderWorkflow",
  "Message": {
    "Order": {
      "Data": {
        (string)"Sentence": "i love my name",
        "Options": {
            (boolean)"Simplify" : true,
            (IReadOnlyCollection<string>) LanguageAffinity : [ "FR", "EN" ]
        }
      },
      "OrderQuery": {
        "Verb": {
          (string)"Verb": "Extract"
        },
        "Arguments": [
          {
            (string)"Argument": "Sentence"
          },
          {
            (string)"Argument": "Meaning"
          }
        ]
      },
      (Guid)"ProcessId": "0bfef4a5-c8a4-4816-81d1-6f7bf1477f65"
    },
    (string)"ReturnTypeFullName": "Viki.Api.Server.Data.SentenceMeaningMsg,, Viki.Api.Server.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
  },
  (boolean)"LocalAffinity": false
}

奇怪的是,它尝试反序列化发送它的WCF部分中的对象,而不是在应该接收该元素的LightHouse中,并转移到代理进行处理。

4 个答案:

答案 0 :(得分:2)

所以这就是我认为可能出现的问题......问题是使用多态序列化程序(如JSON.NET或Hyperion)在.NET Core应用程序和.NET Framework应用程序之间传输序列化内容是一项不受支持的操作。至少是Akka.NET,但也在用户使用CLR类型作为消息的有线格式的任何其他运行时中。

关于why we don't support this in Akka.NET, from the v1.3.0 release notes的简要说明:

  

作为旁注:.NET 4.5上的Akka.NET与.NET Core上的Akka.NET不兼容;这是由于对.NET Core上的CLR中的基本类型进行了根本性更改。这是目前.NET中许多不同的序列化器和网络库面临的常见问题。您可以使用我们在此处开发的X-plat序列化器:#2947 - 如果您正在考虑构建混合.NET和.NET Core集群,请对该线程发表评论。

&#34;基本变化&#34;在这种情况下,像string 这样的类型的命名空间在.NET 4. *和.NET Core上是不同的,因此不能解释这些差异的多态序列化器将会抛出这种类型的异常。

如果您想使用它,我们确实有一个解决方法:

https://github.com/akkadotnet/akka.net/pull/2947

您需要在Lighthouse和您的.NET 4.7.1应用程序中使用JSON.NET注册该序列化程序compat层。

答案 1 :(得分:0)

这是请求“无法加载System.Private.CoreLib”的最佳结果,因此我发布了ASP.NET Core API和.NET客户端的解决方法。

如果json序列化程序类型处理设置为auto

settings.TypeNameHandling = TypeNameHandling.Auto;

序列化器将包含多态类型的类型信息。迁移到.NET Core后,一些客户端报告了异常,并且响应主体包含以下类型描述符:

"$type":"System.String[], System.Private.CoreLib"

在API模型中,属性类型定义为IEnumerable<string>,这迫使序列化程序包括Array的实际类型。解决方案是将IEnumerable<string>替换为string[]或允许序列化程序省略类型描述符的任何其他具体类型。

答案 2 :(得分:0)

如果在 .NET Framework 应用程序中反序列化过程中发生此问题,并且您无法对收到的 JSON 执行任何操作,那么您可以扩展 DefaultSerializationBinder 并在 JsonSerializerSettings 中使用它来反序列化由.NET Core 应用程序:

internal sealed class DotNetCompatibleSerializationBinder : DefaultSerializationBinder
{
    private const string CoreLibAssembly = "System.Private.CoreLib";
    private const string MscorlibAssembly = "mscorlib";

    public override Type BindToType(string assemblyName, string typeName)
    {
        if (assemblyName == CoreLibAssembly)
        {
            assemblyName = MscorlibAssembly;
            typeName = typeName.Replace(CoreLibAssembly, MscorlibAssembly);
        }

        return base.BindToType(assemblyName, typeName);
    }
}

然后:

var settings = new JsonSerializerSettings()
{
    SerializationBinder = new DotNetCompatibleSerializationBinder()
};

答案 3 :(得分:-1)

对于基本类型尝试使用

serializer.TypeNameHandling = TypeNameHandling.Auto

可以忽略 Json 中的 System.Private.CoreLib 命名空间