使用继承时 protobuf-net Guid 反序列化为 Guid.Empty
当 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 protobuf-net,它需要提前了解继承(实际上,
DataContractSerializer
也是如此,通常 - 通过[KnownType(...)]
)。在 protobuf-net 的情况下,它还需要一个唯一的键来区分它们,例如:(即需要告知基类型有关派生类型的信息)
请注意,每个数字中的数字只需唯一类型,因此包含中的“3”与
GatewayPageAddedToSite
中的“3”之间不会发生冲突 - 实际上,GatewayPageAddedToSite
可以使用“1”和“2”(如果需要)。如果生成了域模型,那么一个单独的部分类文件可能会有所帮助:
如果您真的不想用这些东西打乱您的模型,那么在 v2 中您可以在运行时执行此操作:
其中任何一个都可以使其工作吗?
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:(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:
If you really don't want to upset your model with these things, then in v2 you can do this at runtime instead:
any of that make it work?