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

标签 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 入口点。

发送的对象仅包含 bool 值、字符串、Guid 和字符串属性数组。

编辑 08-05-2018

发送的对象是这样的:

{
  (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
}

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

我尝试在发送 WCF 部分之前对结果进行序列化和反序列化,结果成功了。

var serializer = this._system.Serialization.FindSerializerFor(result);
var bytes = serializer.ToBinary(result);
var data = serializer.FromBinary(bytes, result.GetType());

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

最佳答案

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

如果 json 序列化器类型处理设置为自动

settings.TypeNameHandling = TypeNameHandling.Auto;

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

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

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

如果上述方法不起作用,例如当您使用 Dictionary<string, object> 时你可以实现自定义 SerializationBinder :

public class NetCoreSerializationBinder : DefaultSerializationBinder
{
    private static readonly Regex regex = new Regex(
        @"System\.Private\.CoreLib(, Version=[\d\.]+)?(, Culture=[\w-]+)(, PublicKeyToken=[\w\d]+)?");

    private static readonly ConcurrentDictionary<Type, (string assembly, string type)> cache =
        new ConcurrentDictionary<Type, (string, string)>();

    public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        base.BindToName(serializedType, out assemblyName, out typeName);

        if (cache.TryGetValue(serializedType, out var name))
        {
            assemblyName = name.assembly;
            typeName = name.type;
        }
        else
        {
        if (assemblyName.AsSpan().Contains("System.Private.CoreLib".AsSpan(), StringComparison.OrdinalIgnoreCase))
            assemblyName = regex.Replace(assemblyName, "mscorlib");

        if (typeName.AsSpan().Contains("System.Private.CoreLib".AsSpan(), StringComparison.OrdinalIgnoreCase))
            typeName = regex.Replace(typeName, "mscorlib");    
            cache.TryAdd(serializedType, (assemblyName, typeName));
        }
    }
}

并在JsonSerializerSettings中注册:

settings.SerializationBinder = new NetCoreSerializationBinder();

注意: .AsSpan()用于字符串比较的添加是为了向后兼容 .NET Framework。它没有害处,但 .NET Core 3.1+ 不需要,请随意放弃它。

关于c# - .Net Standard 4.7.1 在序列化期间无法加载 System.Private.CoreLib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50190568/

相关文章:

c# - 如何在 UWP 中为路径控制创建共享样式?

.net - 如何创建目标框架为 .NET Standard 2.0 的 F# 库?

c# - 将组合框绑定(bind)到 2 个数据源 : Table & Enum

C# 从第二个线程绘制到位图

c# - 如何将 CaSTLe Activerecord 转换为纯 NHibernate 或 Fluent NHibernate?

c# - 声明属性时 "=>"在 .Net C# 中做什么?

c# - 在 .NET 4.5 中使用 HttpClient 进行编码

c# - C#使线程等待计时器

C#和mysql重复查询

c# - 无法为 netstandard1.x 项目安装 Netstandard1.x Nuget 包