Search code examples
c#.netxml-serializationdatacontractserializer

Remove DataMember by Creating a new base class and obsoleting the derived class


I have a class, which I no longer want to use. I have created a base class and made my obsolete class a child of the new, base class.

Data-wise, the only difference between the two classes is a single DataMember property.

I have a class that has a property that referenced derived class in a property (also DataMember). I have replaced that type with the base type.

On deserialization, I get the error message Deserialized object with reference id 'iXX' not found in stream.

If I move the DataMember from my derived class to the base class. The exception goes away.

I know I can't modify the DataContract. I was hoping to create a new class and allow the other, obsolete class to fall off over time.

Can I do this? Why do I get this exception?

*EDIT: It looks like the xml element has a type attribute when inheritence is involved. I'm guessing that's why the deserialization is failing.

**EDIT:

Serialize with this:

[DataContract(IsReference = true)]
public class DerivedType    
{
    [DataMember]
    public Dictionary<object,object> DataMemberThatIDoNotNeed { get; set; }
}

[DataContract(IsReference = true)]
public class Class1
{
    [DataMember]
    //Previously was DerivedType before BaseType was introduced
    public DerivedType MyBaseType { get; set; }      
}

Then, deserialize with this:

[DataContract(IsReference = true)]
[KnownType(typeof(DerivedType))]
public class BaseType
{

}

[DataContract(IsReference = true)]    
public class DerivedType : BaseType
{
    [DataMember]
    public Dictionary<object,object> DataMemberThatIDoNotNeed { get; set; }
}

[DataContract(IsReference = true)]
public class Class1
{
    [DataMember]
    //Previously was DerivedType before BaseType was introduced
    public BaseType MyBaseType { get; set; }
}

Solution

  • Well, I executed the following code with your objects:

    var class1 = new Class1 {MyBaseType = new DerivedType()};
    
    var serializer = new DataContractSerializer(typeof (Class1));
    serializer.WriteObject(File.Create(filename), class1);
    

    then I changed Class1 to:

    [DataContract(IsReference = true)]
    public class Class1
    {
        [DataMember]
        public DerivedType MyBaseType { get; set; }
    }
    

    and the following code still works:

    var readObject = new DataContractSerializer(typeof (Class1)).ReadObject(File.OpenRead(filename));
    
    readObject.Should().NotBeNull(); // it is not null
    

    Maybe you need to show your serialization code to add more specifics.