1

我在使用 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'd 类(简化,但演示了我能想到的相关语义)。使用 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 依赖;如果是这种情况,我们可能会创建代理 DTO 实体,其中所有公共属性都具有 protobuf 属性。(这是我对所有声明性序列化模型的主观问题;这是一种普遍存在的模式,我理解它为什么会出现,但是 IMO,如果我们可以将一个人送上月球,那么“正常”应该是拥有对象和序列化合同解耦。;-) )

谢谢!

4

1 回答 1

1

同意,您不需要显式依赖 -DataMember很好。并且 protobuf-net 使用相同的逻辑重新忽略等。您如何/在哪里存储数据?以我的经验,最常见的原因是人们正在用不同的数据覆盖缓冲区(或文件),而不是截断它(在流的末尾留下垃圾),如此处所述。这与您的情况有关吗?

于 2010-04-10T06:48:42.203 回答