DataContract classes in WCF can be declared as implementing IExtensibleDataObject to provide in-built support for schema versioning. Any data contracts created through svcutil or Add Service Reference implement the interface, and it’s good practice to implement it for any custom DataContract classes you write. On deserializing, elements which are not declared in the data contract are extracted by the DataContractSerializer and added to the ExtensionDataObject property, so unexpected data is not lost (see Vagif Abilov’s blog post on backwards compatibility with IExtensibleDataObject).
Internally, the ExtensionDataMember holds a convoluted key-value collection of the unrecognised data members. If you want to inspect the contents of the collection it’s a fiddly process as the members are non-public, and the types and interfaces of the members (ExtensionDataMember and IDataNode) are also non-public. The code below allows you to extract the value of an ExtensionDataMember given its name:
private object GetExtensionDataMemberValue(IExtensibleDataObject extensibleObject, string dataMemberName)
object innerValue = null;
PropertyInfo membersProperty = typeof(ExtensionDataObject).GetProperty(“Members”, BindingFlags.NonPublic | BindingFlags.Instance);
IList members = (IList)membersProperty.GetValue(extensibleObject.ExtensionData, null);
foreach (object member in members)
PropertyInfo nameProperty = member.GetType().GetProperty(“Name”, BindingFlags.NonPublic | BindingFlags.Instance);
string name = (string) nameProperty.GetValue(member, null);
if (name == dataMemberName)
PropertyInfo valueProperty = member.GetType().GetProperty(“Value”, BindingFlags.NonPublic | BindingFlags.Instance);
object value = valueProperty.GetValue(member, null);
PropertyInfo innerValueProperty = value.GetType().GetProperty(“Value”, BindingFlags.Public | BindingFlags.Instance);
innerValue = innerValueProperty.GetValue(value, null);
Obviously this is fragile and isn’t appropriate for production solutions, but it can be useful for unit testing or debugging WCF calls, or when you want to confirm the effects of having data contracts which are out of sync between the service and the consumer. Similar code could be used to get the count of extended data members to identify if the DataContract schema is not the correct version, and interestingly, the value and innerValue properties are writeable, so you could update the contents of the unrecognised members.