【问题标题】:Howto ignore unknown types with DataContractSerializer如何使用 DataContractSerializer 忽略未知类型
【发布时间】:2013-01-31 06:36:24
【问题描述】:

我尝试在我的应用程序中使用 DataContractSerializer,以便向后和向前兼容并支持往返(如果可能)。

是否可以支持往返,或者如果不支持,是否可以在以下场景中忽略未知类型?

假设我有一个 ClassWithObject 类,它有一个 object 类型的属性,而我的应用程序的旧版本在这个属性中存储了一个 CurrentAdditionalData 类型的对象。

    [DataContract]
[KnownType(typeof(CurrentAdditionalData))]
public class ClassWithObject : IExtensibleDataObject
{
    #region IExtensibleDataObject Members
    private ExtensionDataObject extensionDataObject_value;
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public ExtensionDataObject ExtensionData
    {
        get
        {
            return extensionDataObject_value;
        }
        set
        {
            extensionDataObject_value = value;
        }
    }
    #endregion

    [DataMember]
    public object AdditionalData { get; set; }
}

[DataContract]
public class CurrentAdditionalData : IExtensibleDataObject
{
    #region IExtensibleDataObject Members
    private ExtensionDataObject extensionDataObject_value;
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public ExtensionDataObject ExtensionData
    {
        get
        {
            return extensionDataObject_value;
        }
        set
        {
            extensionDataObject_value = value;
        }
    }
    #endregion

    [DataMember]
    public int MyProperty { get; set; }
}

对于我的应用程序的新版本,加载此文件没有问题,因为它知道 CurrentAdditionalData 类。

但是如果新版本存储了一个旧版本不知道的 FutureAdditionalData 类型的对象呢?

    [DataContract]
public class FutureAdditionalData : IExtensibleDataObject
{
    #region IExtensibleDataObject Members
    private ExtensionDataObject extensionDataObject_value;
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public ExtensionDataObject ExtensionData
    {
        get
        {
            return extensionDataObject_value;
        }
        set
        {
            extensionDataObject_value = value;
        }
    }
    #endregion

    [DataMember]
    public string Property1 { get; set; }
    [DataMember]
    public float Property2 { get; set; }
    [DataMember]
    public double Property3 { get; set; }
}

如果旧版本试图读取这个文件,它会得到一个SerializationException,因为它不知道这个类型。

是否可以修改旧版本,使其知道未知类型并简单地忽略它们?

或者更好的是,如果旧版本再次保存文件,是否可以将未知对象加载到ExtensionData中并将其原封不动地写出来?

【问题讨论】:

    标签: c# serialization datacontractserializer roundtrip


    【解决方案1】:

    Microsoft 有一个完整的指南来解决这些数据合同问题。 签出:https://msdn.microsoft.com/en-us/library/ms731138.aspx

    我刚刚意识到您的意思是更改数据类型,而不是简单地添加/删除成员。不,您可以通过为新类型创建新成员而不是更改现有成员来适当地处理此问题。更改 dataTypes 是 API 的重大更改。

    查看此指南,了解哪些更改构成 API 的版本更改: http://blogs.msdn.com/b/craigmcmurtry/archive/2006/07/23/676104.aspx

    【讨论】:

    • 成员的数据类型是简单的对象。这是因为 ClassWithObject 不知道对象的类型,它只是存储对象。应用程序的未来版本现在将对象设置为新类型。显然旧版本没有设置属性 [KnownType(typeof(FutureAdditionalData))] 并给出 SerializationException。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 2016-06-13
    相关资源
    最近更新 更多