繁体   English   中英

继承更改的DataContract

[英]DataContract with inheritance change

我正在使用DataContracts来序列化对象。 假设我已经序列化了以这种方式构建的数据:

[DataContract]
public class Dog : IExtensibleDataObject
{
    [DataMember]
    public int age;

    [DataMember]
    public string name;

    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }
}

现在我正在改变我的架构,我想用这些类读取以前的序列化数据:

[DataContract]
[KnownType(typeof(Dog))]
public class Animal : IExtensibleDataObject
{
    [DataMember]
    public string name;

    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }
}

[DataContract]
public class Dog : Animal
{
    [DataMember]
    public int age;
}

但我获得name = null。 我知道这取决于顺序:文件首先保存为age,然后从name开始读取,因为它在基类上。
有没有办法处理这个,可能是通过改变顺序?

我不认为这是可能的。

过去的xml本来就是

<dog>
    <name>Bob</name>
    <age>10</age>
</dog>

它现在期待

<animal>
    <name>Bob</name>
    <dog>
        <age>10</age>
    </dog>
</animal>

对于在新DataContract上序列化的任何内容,该属性更高。 使用IExtensibleDataObject方法更改继承层次结构是一个重大变化。

允许继承与数据协定一起使用,前提是继承不用作版本控制机制并遵循某些规则。 如果类型派生自某个基类型,请不要在未来版本中从不同的基类型派生(除非它具有相同的数据协定)。 这有一个例外:您可以在数据协定类型与其基本类型之间的层次结构中插入一个类型,但前提是它不包含与其他类型的任何可能版本中的其他成员具有相同名称的数据成员。层次结构。 通常,在同一继承层次结构的不同级别使用具有相同名称的数据成员可能会导致严重的版本控制问题,应该避免使用。

更多最佳实践:数据合同版本控制

编辑1:

您也许可以尝试在Animal中创建名称虚拟并在Dog中覆盖它? 或者一些疯狂的方法来强制序列化的新版本在dog下有名字。 即,像,

[DataContract] 
[KnownType(typeof(Dog))] 
public class Animal : IExtensibleDataObject 
{
    public virtual string name; 

    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; } 
} 

[DataContract] 
public class Dog : Animal 
{ 
    [DataMember] 
    public override string name; 

    [DataMember] 
    public int age; 
} 

您应该查看本SO帖子中讨论的WCF合同版本控制

基本上,您需要在ServiceContract上分配一个Namespace ,如果您希望在合同发展时需要向后兼容性,请保留旧版本和旧版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM