如何使用DataContractSerializer忽略未知类型

时间:2013-02-15 09:56:43

标签: c# serialization datacontractserializer roundtrip

我尝试在我的应用程序中使用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中,如果旧版本再次保存文件,可以不加修改地将其写出来?

1 个答案:

答案 0 :(得分:0)

Microsoft提供了解决数据合同这类问题的完整指南。 查看:https://msdn.microsoft.com/en-us/library/ms731138.aspx

我刚刚意识到你意味着要更改dataType,而不是简单地添加/删除成员。不,您通过为新类型创建新成员而不是通过更改现有成员来适当地处理此问题。更改dataTypes是API的重大变化。

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