我遇到了使用protobuf-net反序列化ORM生成的实体的某些Guid属性的问题。
以下是代码的简化示例(重现场景的大多数元素,但不会重现行为;我无法公开我们的内部实体,所以我正在寻找解释异常的线索)。假设我有一个类Account
,其中包含AccountID
只读guid和AccountName
读写字符串。我序列化&立即反序列化一个克隆。
反序列化在反序列化时抛出Incorrect wire-type deserializing Guid
异常。
以下是使用示例...
Account acct = new Account() { AccountName = "Bob's Checking" };
Debug.WriteLine(acct.AccountID.ToString());
using (MemoryStream ms = new MemoryStream())
{
ProtoBuf.Serializer.Serialize<Account>(ms, acct);
Debug.WriteLine(Encoding.UTF8.GetString(ms.GetBuffer()));
ms.Position = 0;
Account clone = ProtoBuf.Serializer.Deserialize<Account>(ms);
Debug.WriteLine(clone.AccountID.ToString());
}
这是一个ORM类的例子(简化,但演示了我能想到的相关语义)。使用shell游戏通过公开支持字段来反序列化只读属性(“无法写入”基本上变成“不应该写”,但我们可以扫描代码以查找分配给这些字段的实例,因此hack适用于我们的目的)。
同样,不重现异常行为;我正在寻找关于可以:
的线索[DataContract()]
[Serializable()]
public partial class Account
{
public Account()
{
_accountID = Guid.NewGuid();
}
[XmlAttribute("AccountID")]
[DataMember(Name = "AccountID", Order = 1)]
public Guid _accountID;
/// <summary>
/// A read-only property; XML, JSON and DataContract serializers all seem
/// to correctly recognize the public backing field when deserializing:
/// </summary>
[IgnoreDataMember]
[XmlIgnore]
public Guid AccountID
{
get { return this._accountID; }
}
[IgnoreDataMember]
protected string _accountName;
[DataMember(Name = "AccountName", Order = 2)]
[XmlAttribute]
public string AccountName
{
get { return this._accountName; }
set { this._accountName = value; }
}
}
XML,JSON和DataContract序列化程序似乎都很好地序列化/反序列化这些对象图,因此属性排列基本上可行。我已经尝试过使用列表与单个实例,不同前缀样式等的protobuf-net,但在反序列化时仍然总是得到'错误的线型... Guid'异常。
所以具体问题是,有没有任何已知的解释/解决方法?我不知道试图追踪什么情况(在真实的代码而不是示例中)可能导致它。
我们希望不必直接在实体层中创建protobuf依赖项;如果是这种情况,我们可能会创建具有protobuf属性的所有公共属性的代理DTO实体。 (这是我对所有声明序列化模型的一个主观问题;它是一种无处不在的模式,我理解它为什么会出现,但IMO,如果我们可以把一个人放在月球上,那么“正常”应该是有对象和序列化合同解耦。;-))
谢谢!
答案 0 :(得分:1)
同意,你不应该需要明确的依赖 - DataMember
没问题。并且protobuf-net使用相同的逻辑重新忽略等。您如何/在哪里存储数据?根据我的经验,最常见的原因是人们用不同的数据覆盖缓冲区(或文件),而不是截断它(在流的末尾留下垃圾),as discussed here。这与你的情景有关吗?