How to deserialize an object using custom serializable properties?

I am trying to serialize / deserialize a collection of interfaces that are mostly not supported. I found a question on SO that claims to provide serializable shell properties for these interface-dependent properties. So what I have:

public class Serialize { public Serialize() { this.SCollection = new SerializableInterfacesCollection<ObservableCollection<A>>(new ObservableCollection<A>()); } [XmlIgnore()] public ObservableCollection<A> Collection { get { return this.SCollection.Value; } set { SCollection.Value = value; } } public SerializableInterfacesCollection<ObservableCollection<A>> SCollection { get; set; } } public interface A { string Str { get; set; } int Int { get; set; } // bad properties... very bad: BB { get; set; } ObservableCollection<B> Collection {get;set;} } public interface B { string Label { get; set; } string Value { get; set; } } public class AImpl: A { public AImpl() { SB = new SerializableInterface<B>(); SCollection = new SerializableInterfacesCollection<ObservableCollection<B>>(new ObservableCollection<B>()); } [XmlAttribute()] public string Type = typeof(AImpl).FullName; public string Str {get;set;} public int Int {get;set;} [XmlIgnore()] public BB { get { return SB.Value; } set { SB.Value = value; } } public SerializableInterface<B> SB; [XmlIgnore()] public ObservableCollection<B> Collection { get { return SCollection.Value; } set { SCollection.Value = value; } } public SerializableInterfacesCollection<ObservableCollection<B>> SCollection { get; set; } } public class BImpl01: B { [XmlAttribute()] public string Type = typeof(BImpl01).FullName; public string Label {get;set;} public string Value {get;set;} } public class BImpl02: B { [XmlAttribute()] public string Type = typeof(BImpl02).FullName; public string Label {get;set;} public string Value {get;set;} } 

Everything works fine if interface A does not include "bad properties" (and, of course, they do not appear in the AImpl class). If he does, than the collection item does not deserialize and stops after deserializing the first property of interface B.

Here are the wrappers:

 public class SerializableInterface<T>: IXmlSerializable { public SerializableInterface(T value) { Value = value; } public SerializableInterface() { } public T Value { get; set; } public const string TypeAttr = "Type"; public const string NullAttrValue = "null"; #region IXmlSerializable Members public System.Xml.Schema.XmlSchema GetSchema() { return null; } public virtual void ReadXml(System.Xml.XmlReader reader) { if (!reader.HasAttributes) throw new FormatException("expected a type attribute!"); string type = reader.GetAttribute(TypeAttr); reader.Read(); // consume the value if (type == NullAttrValue) return;// leave T at default value XmlSerializer serializer = new XmlSerializer(Type.GetType(type)); this.Value = (T)serializer.Deserialize(reader); } public virtual void WriteXml(System.Xml.XmlWriter writer) { if (Value == null) { writer.WriteAttributeString(TypeAttr, NullAttrValue); return; } try { var type = Value.GetType(); var ser = new XmlSerializer(type); writer.WriteAttributeString(TypeAttr, type.FullName); ser.Serialize(writer, Value); } catch (Exception e) { // some logging throw e; } } #endregion } public class SerializableInterfacesCollection<T>: SerializableInterface<T> where T: IList, new() { public SerializableInterfacesCollection() { } public SerializableInterfacesCollection(T value) : base(value) {} #region IXmlSerializable Members public override void ReadXml(System.Xml.XmlReader reader) { try { if (!reader.HasAttributes) throw new FormatException("No " + TypeAttr + " in element"); string type = reader.GetAttribute(TypeAttr); if (string.IsNullOrEmpty(type) || type == NullAttrValue || type != typeof(T).FullName) return; reader.Read(); Value = new T(); while (reader.NodeType != XmlNodeType.EndElement) { string typename = reader.GetAttribute(TypeAttr); if (string.IsNullOrEmpty(typename)) { throw new FormatException("Collection element has to have " + TypeAttr + " attribute specifing its type"); } Type t = Type.GetType(typename); if (null == t.GetInterface(typeof(T).GetProperty("Item").PropertyType.FullName)) break; XmlSerializer xs = new XmlSerializer(t); var o = xs.Deserialize(reader); Value.Add(o); } } catch (Exception e) { // some logging throw e; } } public override void WriteXml(System.Xml.XmlWriter writer) { if (Value == null) { writer.WriteAttributeString(TypeAttr, NullAttrValue); return; } try { writer.WriteAttributeString(TypeAttr, Value.GetType().FullName); foreach (var el in Value) { var ser = new XmlSerializer(el.GetType()); ser.Serialize(writer, el); } } catch (Exception e) { // some logging throw e; } } #endregion } 

and here is the method generating the data for the tests:

  private Serialize makeA() { Serialize result = new Serialize(); for (int i = 0; i < 10; ++i) { A a = new AImpl() { Str = "str " + i, Int = i, B = makeB(i) }; for (int j = 0; j < 10; ++j) { a.Collection.Add(makeB(j)); } result.Collection.Add(a); } return result; } B makeB(int i) { if (i % 2 == 0) { return new BImpl01(){Label= "Blabel " + i, Value="value b"+i}; } else { return new BImpl02(){Label= "B2label " + i, Value="value b2"+i}; } } 
+1
c # deserialization xml-serialization
Sep 28 2018-11-11T00:
source share

No one has answered this question yet.

See similar questions:

68
XML serialization of an interface property

or similar:

3575
How to list an enumeration?
2105
Deep Cloning Objects
1743
How do you give C # Auto-Property the default?
1064
How to sort the <T> list by property in an object
872
Deserialize JSON to a dynamic C # object?
289
How to implement custom JsonConverter in JSON.NET to deserialize a list of base class objects?
twenty
XmlSerializer and nullable Attributes
6
XML deserialization
one
XMLSerializer does not deserialize XML
one
get int value from XmlTextAttribute when deserializing xml to class in C #



All Articles