简体   繁体   English

继承更改的DataContract

[英]DataContract with inheritance change

I'm using DataContracts to serialize objects. 我正在使用DataContracts来序列化对象。 Suppose I have serialized a data structured in this way: 假设我已经序列化了以这种方式构建的数据:

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

    [DataMember]
    public string name;

    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }
}

Now I'm changing my architecture and I would like to read the previously serialized data with this classes: 现在我正在改变我的架构,我想用这些类读取以前的序列化数据:

[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;
}

but I obtain name = null. 但我获得name = null。 I know that this depends on the order: the file was saved with age for first and then read starting from name, because it is on the base class. 我知道这取决于顺序:文件首先保存为age,然后从name开始读取,因为它在基类上。
Is there a way to handle this, maybe by changing the order? 有没有办法处理这个,可能是通过改变顺序?

I don't think that's possible. 我不认为这是可能的。

The xml in the past would have been 过去的xml本来就是

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

Its now expecting 它现在期待

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

The property is higher up in anything that's serialized on the new DataContract. 对于在新DataContract上序列化的任何内容,该属性更高。 Changing inheritance heirarchy is a breaking change with the IExtensibleDataObject method. 使用IExtensibleDataObject方法更改继承层次结构是一个重大变化。

The use of inheritance together with data contracts is allowed, provided that inheritance is not used as a versioning mechanism and that certain rules are followed. 允许继承与数据协定一起使用,前提是继承不用作版本控制机制并遵循某些规则。 If a type derives from a certain base type, do not make it derive from a different base type in a future version (unless it has the same data contract). 如果类型派生自某个基类型,请不要在未来版本中从不同的基类型派生(除非它具有相同的数据协定)。 There is one exception to this: you can insert a type into the hierarchy between a data contract type and its base type, but only if it does not contain data members with the same names as other members in any possible versions of the other types in the hierarchy. 这有一个例外:您可以在数据协定类型与其基本类型之间的层次结构中插入一个类型,但前提是它不包含与其他类型的任何可能版本中的其他成员具有相同名称的数据成员。层次结构。 In general, using data members with the same names at different levels of the same inheritance hierarchy can lead to serious versioning problems and should be avoided. 通常,在同一继承层次结构的不同级别使用具有相同名称的数据成员可能会导致严重的版本控制问题,应该避免使用。

More at Best Practices: Data Contract Versioning 更多最佳实践:数据合同版本控制

Edit 1: 编辑1:

You could perhaps try making Name virtual in Animal and overriding it in Dog? 您也许可以尝试在Animal中创建名称虚拟并在Dog中覆盖它? Or some crazy method to force the serialized new version to have name under dog. 或者一些疯狂的方法来强制序列化的新版本在dog下有名字。 ie something like, 即,像,

[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; 
} 

You should take a look at WCF Contract Versioning discussed in this SO post . 您应该查看本SO帖子中讨论的WCF合同版本控制

Essentially you need to assign a Namespace on your ServiceContract and keep both the new and old versions around if you want backwards compatibility as your contract evolves. 基本上,您需要在ServiceContract上分配一个Namespace ,如果您希望在合同发展时需要向后兼容性,请保留旧版本和旧版本。

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

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