1

protobuf-netを使用してORMで生成されたエンティティの特定のGuidプロパティを逆シリアル化する際に問題が発生します。

コードの簡略化された例を次に示します(シナリオのほとんどの要素を再現しますが、動作は再現しません。内部エンティティを公開できないため、例外を説明するための手がかりを探しています)。読み取り専用のGUIDと読み取り/書き込み文字列をAccount持つクラスがあるとします。クローンをシリアル化し、すぐに逆シリアル化します。AccountIDAccountName

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されたクラスの例です(簡略化されていますが、私が考えることができる関連するセマンティクスを示しています)。シェルゲームを使用して、バッキングフィールドを公開することにより、読み取り専用プロパティを逆シリアル化します(「書き込み不可」は基本的に「書き込み不可」になりますが、これらのフィールドに割り当てるインスタンスのコードをスキャンできるため、ハックは目的)。

繰り返しますが、これは例外の動作を再現しません。私は何ができるかについての手がかりを探しています:

[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は、人を月に乗せることができれば、「通常」はオブジェクトとシリアル化契約を持つ必要があります分離。;-))

ありがとう!

4

1 に答える 1

1

同意しました、明示的な依存関係は必要ありません-DataMember問題ありません。そして、protobuf-net は無視などと同じロジックを使用します。どのように/どこにデータを保存していますか? 私の経験では、これの最も一般的な原因は、ここで説明されているように、人々がバッファー (またはファイル) を別のデータで上書きし、それを切り捨てる (ストリームの最後にゴミを残す) ことではないことです。これはあなたのシナリオに関連していますか?

于 2010-04-10T06:48:42.203 に答える