使用继承时 protobuf-net Guid 反序列化为 Guid.Empty

发布于 2024-12-08 13:11:08 字数 1968 浏览 0 评论 0原文

当 Guid 是在消息基类中定义时,我在反序列化 Guid 时遇到问题。当我收到以下消息时。

 [DataContract]
public abstract class GatewayPageEvent:IDomainEvent
{
    protected GatewayPageEvent()
    {
        On = DateTime.Now;
    }
    [DataMember(Order = 1)] public Guid GatewayPageId { get; set; }
    [DataMember(Order = 2)] public DateTime On { get; set; }
}
[DataContract]
public class GatewayPageAddedToSite : GatewayPageEvent
{
    [DataMember(Order = 3)]public string Url { get; set; }
    [DataMember(Order = 4)]public string SiteCode { get; set; }
}

GatewayPageId 始终反序列化为 Guid.Empty。这是我编写的失败的单元测试。我有点难住了...

    public string Serialize(object t)
    {
        var memoryStream = new MemoryStream();
        ProtoBuf.Serializer.Serialize(memoryStream, t);
        return Convert.ToBase64String(memoryStream.ToArray());
    }

    public object Deserialize(string value, Type targetType)
    {
        var bytes = Convert.FromBase64String(value);
        var stream = new MemoryStream(bytes);
        return ProtoBuf.Serializer.NonGeneric.Deserialize(targetType, stream);
    }
    [Test]
    public void protobuf_serialization_can_deserialized_guids()
    {
        var originalMessage = new GatewayPageAddedToSite
                                  {GatewayPageId = Guid.NewGuid(), SiteCode = "dls", Url = "test"};
        var serializedMessage = Serialize(originalMessage);
        var @event = (GatewayPageAddedToSite)Deserialize(serializedMessage, typeof(GatewayPageAddedToSite));
        Assert.AreEqual(@event.GatewayPageId, originalMessage.GatewayPageId);
    }

我知道 Guid 工作得很好,因为下面的单元测试工作得很好。

[Test]
    public void guids_work_fine()
    {
        var original = Guid.NewGuid();
        var serialized = Serialize(original);
        var deserialized = (Guid) Deserialize(serialized, typeof (Guid));
        Assert.AreEqual(original,deserialized);
    }

我对合同的定义是否错误?或者这是 protobuf-net 的问题?

I'm having issues deserializing a Guid when the Guid is defined in a message base class. When I have the following message.

 [DataContract]
public abstract class GatewayPageEvent:IDomainEvent
{
    protected GatewayPageEvent()
    {
        On = DateTime.Now;
    }
    [DataMember(Order = 1)] public Guid GatewayPageId { get; set; }
    [DataMember(Order = 2)] public DateTime On { get; set; }
}
[DataContract]
public class GatewayPageAddedToSite : GatewayPageEvent
{
    [DataMember(Order = 3)]public string Url { get; set; }
    [DataMember(Order = 4)]public string SiteCode { get; set; }
}

GatewayPageId is always deserializing as Guid.Empty. Here's a unit test I wrote that fails. I'm kinda stumped...

    public string Serialize(object t)
    {
        var memoryStream = new MemoryStream();
        ProtoBuf.Serializer.Serialize(memoryStream, t);
        return Convert.ToBase64String(memoryStream.ToArray());
    }

    public object Deserialize(string value, Type targetType)
    {
        var bytes = Convert.FromBase64String(value);
        var stream = new MemoryStream(bytes);
        return ProtoBuf.Serializer.NonGeneric.Deserialize(targetType, stream);
    }
    [Test]
    public void protobuf_serialization_can_deserialized_guids()
    {
        var originalMessage = new GatewayPageAddedToSite
                                  {GatewayPageId = Guid.NewGuid(), SiteCode = "dls", Url = "test"};
        var serializedMessage = Serialize(originalMessage);
        var @event = (GatewayPageAddedToSite)Deserialize(serializedMessage, typeof(GatewayPageAddedToSite));
        Assert.AreEqual(@event.GatewayPageId, originalMessage.GatewayPageId);
    }

I know Guids work fine because the following unit test works just fine.

[Test]
    public void guids_work_fine()
    {
        var original = Guid.NewGuid();
        var serialized = Serialize(original);
        var deserialized = (Guid) Deserialize(serialized, typeof (Guid));
        Assert.AreEqual(original,deserialized);
    }

Am I defining my contract wrong? Or is this a problem with protobuf-net?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风吹短裙飘 2024-12-15 13:11:08

使用 protobuf-net,它需要提前了解继承(实际上,DataContractSerializer 也是如此,通常 - 通过 [KnownType(...)])。在 protobuf-net 的情况下,它还需要一个唯一的键来区分它们,例如:(

[DataContract, ProtoInclude(3, typeof(GatewayPageAddedToSite))]
public abstract class GatewayPageEvent:IDomainEvent
{...}
[DataContract]
public class GatewayPageAddedToSite : GatewayPageEvent
{...}

即需要告知基类型有关派生类型的信息)

请注意,每个数字中的数字只需唯一类型,因此包含中的“3”与 GatewayPageAddedToSite 中的“3”之间不会发生冲突 - 实际上,GatewayPageAddedToSite 可以使用“1”和“2”(如果需要)。

如果生成了域模型,那么一个单独的部分类文件可能会有所帮助:

[ProtoInclude(3, typeof(GatewayPageAddedToSite)]
partial class GatewayPageEvent {}

如果您真的不想用这些东西打乱您的模型,那么在 v2 中您可以在运行时执行此操作:

RuntimeTypeModel.Default[typeof(GatewayPageEvent)]
      .AddSubType(3, typeof(GatewayPageAddedToSite));

其中任何一个都可以使其工作吗?

With protobuf-net, it needs to know about inheritance ahead of time (actually, so does DataContractSerializer, usually - via [KnownType(...)]). In the case of protobuf-net, it also needs a unique key to distinguish them, something like:

[DataContract, ProtoInclude(3, typeof(GatewayPageAddedToSite))]
public abstract class GatewayPageEvent:IDomainEvent
{...}
[DataContract]
public class GatewayPageAddedToSite : GatewayPageEvent
{...}

(i.e. the base-type needs to be told about the derived types)

Note that the numbers only need to be unique within each type, so there is no collision between the "3" in the include vs the "3" in GatewayPageAddedToSite - and actually, GatewayPageAddedToSite could use "1" and "2" if it wants.

If your domain model is generated, then a separate partial class file might help:

[ProtoInclude(3, typeof(GatewayPageAddedToSite)]
partial class GatewayPageEvent {}

If you really don't want to upset your model with these things, then in v2 you can do this at runtime instead:

RuntimeTypeModel.Default[typeof(GatewayPageEvent)]
      .AddSubType(3, typeof(GatewayPageAddedToSite));

any of that make it work?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文