protobuf-net:错误的线型异常反序列化Guid属性

时间:2010-04-10 05:28:48

标签: c# protobuf-net

我遇到了使用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,如果我们可以把一个人放在月球上,那么“正常”应该是有对象和序列化合同解耦。;-))

谢谢!

1 个答案:

答案 0 :(得分:1)

同意,你不应该需要明确的依赖 - DataMember没问题。并且protobuf-net使用相同的逻辑重新忽略等。您如何/在哪里存储数据?根据我的经验,最常见的原因是人们用不同的数据覆盖缓冲区(或文件),而不是截断它(在流的末尾留下垃圾),as discussed here。这与你的情景有关吗?