简体   繁体   English

在 protobuf-net 中序列化一个 IEnumerable

[英]Serializing an IEnumerable in protobuf-net

I have a library of fairly heavy-weight DTOs that is currently being used by some WCF services.我有一个相当重量级的 DTO 库,目前正被一些 WCF 服务使用。 We are attempting to bring it into protobuf-net world, with as little modification as possible.我们正在尝试将它带入 protobuf-net 世界,并尽可能少做修改。 One particular set of items is giving me trouble in serialization.一组特定的项目在序列化方面给我带来了麻烦。 I'm going to simply them here because it gets a little complicated, but the gist of the problem is:我将在这里简单介绍它们,因为它有点复杂,但问题的要点是:

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

I've left out the decorators because I don't they're the problem, mostly because if I add void Add(Key item) { } to KeyCollection the whole thing seems to work.我省略了装饰器,因为我不认为它们是问题,主要是因为如果我将void Add(Key item) { }KeyCollection整个事情似乎都有效。 Otherwise, I run into problems attempting to serialize an instance of ContainerType1 .否则,我会在尝试序列化ContainerType1的实例时遇到问题。

Actually, changing the signature of KeyCollection is kind of prohibitive, so I'm attempting to follow this answer to try to do it programatically.实际上,更改KeyCollection的签名KeyCollection令人望而却步,因此我试图按照此答案尝试以编程方式进行。 Specifically, setting itemType and defaultType to null on the "Keys" ValueMember of ContainerType1 , ContainerType1Base and ContainerBase<Item> .具体来说,在ContainerType1ContainerType1BaseContainerBase<Item>的“Keys” ValueMember上将itemTypedefaultType设置为 null。 I also set IgnoreListHandling to true on KeyCollection ... which totally doesn't work.我还在KeyCollection IgnoreListHandling设置为true ......这完全不起作用。 I get a generic "failed to deserialize" exception on the client, which I can post here if it would help.我在客户端收到一个通用的“无法反序列化”异常,如果有帮助,我可以在这里发布。 On the server side, I serialize it out using Serializer.Serialize() , and I spit out Serializer.GetProto<>() as well as JSON of the object, and they all seem to be work okay.在服务器端,我使用Serializer.Serialize()将其Serializer.Serialize() ,然后吐出Serializer.GetProto<>()以及对象的 JSON,它们似乎都可以正常工作。

How can I turn off the list handling?如何关闭列表处理? Related to that, is there a way to turn on extra debugging while serializing to try to get some more information of the problem?与此相关,有没有办法在序列化时打开额外的调试以尝试获取有关问题的更多信息?

Fundamentally, the code shown looks fine.从根本上说,显示的代码看起来不错。 Unfortunately, there's currently a "feature" in gRPC that means that it discards the original exception when a marshaller (serializer) fails for some reason, so gRPC does not currently expose the actual problem.不幸的是, gRPC目前有一个“功能”,这意味着当编组器(序列化器)由于某种原因失败时,它会丢弃原始异常,因此 gRPC 目前没有暴露实际问题。 I have submitted a fix for this - it may or may not be accepted.我已经为此提交了一个修复程序 - 它可能会或可能不会被接受。

In the interim, I suggest that you simply remove gRPC from the equation, and simulate just the marshaller workload;在此期间,我建议您简单地从等式中删除 gRPC,并仅模拟编组器工作负载; to do this, on the server: generate the data you are trying to send, and do:为此,在服务器上:生成您要发送的数据,然后执行以下操作:

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

and obtain the value of payload (which is just a string ).并获得payload的值(它只是一个string )。 Now at the client, reverse this:现在在客户端,反转这个:

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

My expectation here is that this should throw an exception that will tell you what the actual problem is.我的期望是这应该抛出一个异常,告诉你实际问题是什么。


If the gRPC change gets merged, then the fault should be available via:如果 gRPC 更改被合并,则故障应该可以通过以下方式获得:

catch (RpcException fault)
{
    var originalFault = fault.Status.DebugException;
    // ^^^
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM