Search code examples
c#.netxmldatacontractserializerdatacontract

DataContractResolver without a xsi:type


for the sake of compatibility I need to deserialize an old DataContract-XML into a new model with abstract Types.

Old model and old XML

[DataContract]
class OldType {
  [DataMember] public string Hello;
}

List<OldType> serializeMe = new List<~>(){ new OldType(); }
serializer.WriteObject(..., serializeMe);
<OldType>
  <Hello></Hello>
</OldType>

New Model & XML

[DataContract]
abstract class AbstractType {
 [DataMember] public string Hello;
}

[DataContract]
class NewType : AbstractType {
  // only non serialized fields
}

List<AbstractType> serializeMe = new List<~>(){ new NewType(); }
serializer.WriteObject(..., serializeMe);
<AbstractType i:type="b:NewType" mlns:b="..Namespace">
  <Hello></Hello>
</AbstractType>

Now this obviously doesn't work like that. I was hoping to map the old types to the new abstract types using the DataContractResolver. However the resolver is only called for nodes declared with xsi:type. The last possibility I can think of is using string.replace, however this is just ugly. Any more suggestions? Or can I change the DataContractResolver to ALWAYS get invoked?


Solution

  • Thanks to @dbc I found the right solution. Instead of changing the model to the data I've just added an additional mapping DTO and mapped the name and namespace to the old one. Much better.

    [DataContract(Name="OldType")]
    class DataContractOldType {
      [DataMember] public string Hello;
    
      AbstractType MapToCorrectType() { .... }
    }