
Monday, October 02, 2006
Si habéis probado de serializar un objeto que implemente IDictionary os habréis dado cuenta de que el sistema genera una excepción, indicando que no sabe como serializar dichos objetos.
Por suerte existe una solución bastante fácil (explicada tanto aquí como aquí): implementar la interfaz IXmlSerializable. En los métodos ReadXml ponemos el código para deserializar y en WriteXml el código de serializar.
A continuación un ejemplo (el mérito no es mío, si no de los que han hecho los enlaces anteriores, yo lo único que he hecho ha sido adaptarlo para que use genéricos). Los objetos de la clase SerializableDictionary se pueden serializar a Xml de la manera tradicional. Para más información pasaros por los enlaces anteriores ;-)
public class SerializableDictionary : Dictionary, IXmlSerializable
{
const string NS = <A HREF="">http://blogs.clearscreen.com</A>;
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader r)
{
XmlSerializer keySer = new XmlSerializer(typeof(K));
XmlSerializer valueSer = new XmlSerializer(typeof(V));
r.Read();
r.ReadStartElement("dictionary", NS); while (r.NodeType != System.Xml.XmlNodeType.EndElement)
{
r.ReadStartElement("item", NS);
r.ReadStartElement("key", NS);
K key = (K)keySer.Deserialize(r);
r.ReadEndElement();
r.ReadStartElement("value", NS);
V value = (V)valueSer.Deserialize(r);
r.ReadEndElement();
this.Add(key, value);
r.ReadEndElement();
r.MoveToContent();
}
r.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter w)
{
XmlSerializer keySer = new XmlSerializer(typeof(K));
XmlSerializer valueSer = new XmlSerializer(typeof(V));
w.WriteStartElement("dictionary", NS); foreach (K key in this.Keys)
{
w.WriteStartElement("item", NS);
w.WriteStartElement("key", NS);
keySer.Serialize(w, key);
w.WriteEndElement();
w.WriteStartElement("value", NS);
V value = this[key];
valueSer.Serialize(w, value);
w.WriteEndElement();
w.WriteEndElement();
}
w.WriteEndElement();
}
#endregion
}
Editado @ 04/10: Eliminados unos molestos saltos de línea que impedían leer bien el código fuente... ^_^