1

我有一个相当重量级的 DTO 库,目前一些 WCF 服务正在使用它。我们正试图将它带入 protobuf-net 世界,尽可能少地进行修改。一组特定的项目给我序列化带来了麻烦。我将在这里简单地介绍它们,因为它有点复杂,但问题的要点是:

public class Key
{
   public string Id {get; set;}
}

public class KeyCollection : IEnumerable<Key>
{
   private readonly List<Key> list;

#region IEnumerable
   // etc...
#endregion
}

public class Item
{
   public long Id { get; set; }
}

public abstract class ContainerBase
{ }

public abstract class ContainerBase<T> : ContainerBase
   where T : Item
{ }

public abstract class ContainerType1Base : ContainerBase<Item>
{
   public KeyCollection Keys { get; set; }
}

public class ContainerType1 : ContainerType1Base
{ }

我忽略了装饰器,因为我不认为它们是问题,主要是因为如果我添加void Add(Key item) { }KeyCollection整个东西似乎工作。否则,我在尝试序列化ContainerType1.

实际上,更改的签名KeyCollection有点令人望而却步,所以我试图按照这个答案尝试以编程方式进行。具体来说,在和的“键”上设置itemTypedefaultType为空。我也设置为...这完全行不通。我在客户端上收到一个通用的“无法反序列化”异常,如果有帮助,我可以在这里发布。在服务器端,我使用 将其序列化,并吐出对象的 JSON 以及它们似乎都可以正常工作。ValueMemberContainerType1ContainerType1BaseContainerBase<Item>IgnoreListHandlingtrueKeyCollectionSerializer.Serialize()Serializer.GetProto<>()

如何关闭列表处理?与此相关,有没有办法在序列化时打开额外的调试以尝试获取有关问题的更多信息?

4

1 回答 1

2

从根本上说,显示的代码看起来不错。不幸的是,gRPC 目前有一个“功能”,这意味着当编组器(序列化器)由于某种原因失败时,它会丢弃原始异常,因此 gRPC 目前不会暴露实际问题。我已经为此提交了一个修复程序——它可能会被接受,也可能不会被接受。

在此期间,我建议您简单地从等式中删除 gRPC,并仅模拟编组器工作负载;为此,请在服务器上:生成您尝试发送的数据,然后执行以下操作:

var ms = new MemoryStream();
Serializer.Serialize(ms, yourDataHere);
var payload = Convert.ToBase64String(ms.ToArray());

并获得payload( 这只是 a string) 的值。现在在客户端,反转这个:

var ms = new MemoryStream(Convert.FromBase64String(thatStringValue));
Serialize.Deserialize<YourTypeHere>(ms);

我的期望是这应该抛出一个异常,告诉你实际的问题是什么。


如果 gRPC 更改被合并,那么故障应该可以通过以下方式获得:

catch (RpcException fault)
{
    var originalFault = fault.Status.DebugException;
    // ^^^
}
于 2020-11-19T08:11:46.500 回答