2010-07-28 20 views
23

A veces deseo emular los datos almacenados de mis clases sin configurar un viaje de ida y vuelta a la base de datos. Por ejemplo, digamos que tengo las siguientes clases:Cómo serializar/deserializar clases simples a XML y volver

public class ShoppingCart 
{ 
    public List<CartItem> Items {get; set;} 
    public int UserID { get; set; } 
} 

public class CartItem 
{ 
    public int SkuID { get; set; } 
    public int Quantity { get; set; } 
    public double ExtendedCost { get; set; } 
} 

Digamos que construyo un objeto ShoppingCart en la memoria y quieren "salvar" como un documento XML. ¿Es esto posible a través de algún tipo de método XDocument.CreateFromPOCO(shoppingCart)? ¿Qué tal en la otra dirección: hay una forma integrada de crear un objeto ShoppingCart a partir de un documento XML como new ShoppingCart(xDoc)?

Respuesta

47

XmlSerializer es una forma de hacerlo. DataContractSerializer es otro. Ejemplo con XmlSerializer:

using System.Xml; 
using System.Xml.Serialization; 

//... 

ShoppingCart shoppingCart = FetchShoppingCartFromSomewhere(); 
var serializer = new XmlSerializer(shoppingCart.GetType()); 
using (var writer = XmlWriter.Create("shoppingcart.xml")) 
{ 
    serializer.Serialize(writer, shoppingCart); 
} 

y deserializar de nuevo:

var serializer = new XmlSerializer(typeof(ShoppingCart)); 
using (var reader = XmlReader.Create("shoppingcart.xml")) 
{ 
    var shoppingCart = (ShoppingCart)serializer.Deserialize(reader); 
} 

también para una mejor encapsulación yo le recomendaría el uso de propiedades en lugar de los campos de la clase CartItem.

+0

Gracias por la sugerencia. Tenía la intención de usar propiedades en lugar de campos. Fijo. –

+0

Me llevó un tiempo probar esto, pero funcionó perfectamente. ¡Gracias! –

+3

Ojalá pudiera darte un voto positivo por cada vez que he navegado a esta respuesta en las últimas semanas. Sigue pagando dividendos! –

2

Puede serializar/deserializar con el o el DataContractSerializer.

anotar sus clases con DataContract y DataMember atributos y escribir algo como esto para serializar a XML en un archivo.

ShoppingCart cart = ... 
using(FileStream writer = new FileStream(fileName, FileMode.Create)) 
{ 
    DataContractSerializer ser = new DataContractSerializer(typeof(ShoppingCart)); 
    ser.WriteObject(writer, cart); 
} 
+0

¿Qué sucede si se lanza una excepción durante la serialización? –

+1

@Darin: que a menudo encontrará al comenzar a usar DataContractSerializer. Pero generalmente se reduce a la anotación de atributo de sus clases. El XmlSerializer es más fácil de usar ya que toma casi cualquier cosa que le arroje, pero el DataContractSerializer es más rápido, pero requiere más "trabajo" para ponerlo en funcionamiento. –

+0

@Mikael, creo que no entendiste mi punto. Lo que quiero decir es que si se lanza una excepción, se filtrará un identificador de archivo que es muy malo, ya que bloqueará el archivo y ningún otro proceso podrá hacer nada con él hasta que se mate la aplicación. –

0

Sólo marcar lo que desea realizar una serie de [XmlElement (nombre )] (o XmlAttribute, XmlRoot, etc.) y luego usar el XmlSerializer. Si necesita formateo realmente personalizado, implemente IXmlSerializable.

+2

¿Por qué no proporciona una muestra de código como las otras respuestas en el hilo? – Konstantin

7

Bien hecho. Aquí está el ejemplo para serializar POCO simple en una cadena.

private string poco2Xml(object obj) 
    { 
     XmlSerializer serializer = new XmlSerializer(obj.GetType()); 
     StringBuilder result = new StringBuilder(); 
     using (var writer = XmlWriter.Create(result)) 
     { 
      serializer.Serialize(writer, obj); 
     } 
     return result.ToString(); 
    } 
Cuestiones relacionadas