Software y Aplicaciones Web

Blog de desarrollo de software y aplicaciones web

Comentarios Recientes

Comment RSS

MSDN Home Page (Argentina)


C# Corner


AspAlliance.com

Declaración

Las opiniones en este blog se proporcionan "TAL CUAL", sin garantías,  no confieren derechos y no reflejan, necesariamente, la opinión de quienes me contratan.
Algunas cuestiones que se comentan en el blog no son reales, cualquier similitud con alguna persona viva o muerta no es más que una coincidencia, tampoco significa que necesite terapia, soy asi.

© Copyright 2007-2010

Propaganda

Este sitio implementa publicidad basada en intereses
May
24.
2008

  Serializacion en el Framework 3.5

En el desarrollo de software entendemos por serlialización al proceso por medio del cual se codifica un objeto para ser archivado. Este proceso puede generar un código binario o en XML, particularmente prefiero el último dado que permite que otras aplicaciones manipulen el objeto serializado.

El Microsoft Framework 3.5 facilita las extensiones, lo que nos permite con bastante sencillez realizar esta tarea. En C# 3.0 ToXml Extension Method encontré algo de código que me permitió realizar el siguiente ejercicio.

Lo primero fue codificar una clase utilitaria que me permita serializar y deserializar objetos. En este punto el Framework 3.5 nos permite incluir como parámetro del método una referencia al mismo objeto, en consecuencia este metodo resulta ser una extensión del objeto; es como si el metodo estaría declarado en la definición de la clase. 

   1:   
   2:  using System;
   3:  using System.IO;
   4:  using System.Xml.Serialization;
   5:   
   6:  namespace Extensions
   7:  {
   8:      /// <summary>
   9:      /// Extensions to serialize and deserialize any objects in C# 3.0
  10:      /// Warning, objects to be serialized need a constructor without parameters
  11:      /// 
  12:      /// This only work with C# 3.0, it have the ability to extend types
  13:      /// 
  14:      /// </summary>
  15:      public static class XmlConvertExtensions
  16:      {
  17:          /// <summary>
  18:          /// Serialize any object that have a constructor without parameters
  19:          /// </summary>
  20:          /// <param name="obj"></param>
  21:          /// <returns>A string in XML format having all properties and values for the object</returns>
  22:          public static String ToXml(this object obj)
  23:          {
  24:              XmlSerializer s = new XmlSerializer(obj.GetType());
  25:              using (StringWriter writer = new StringWriter())
  26:              {
  27:                  s.Serialize(writer, obj);
  28:                  return writer.ToString();
  29:              }
  30:          }
  31:          /// <summary>
  32:          /// Deserialize a previous serialized object
  33:          /// </summary>
  34:          /// <typeparam name="T">typeof object to deserialize</typeparam>
  35:          /// <param name="data">string in XML format having properties and values for the object</param>
  36:          /// <returns>Reference to the object</returns>
  37:          public static T ConvertTo<T>(this string data)
  38:          {
  39:              XmlSerializer s = new XmlSerializer(typeof(T));
  40:              using (StringReader reader = new StringReader(data))
  41:              {
  42:                  object obj = s.Deserialize(reader);
  43:                  return (T)obj;
  44:              }
  45:          }
  46:      }
  47:  }

Luego fue necesario escribir una clase que me permita probar los metodos de la clase utilitaria. En este caso se trata de algo muy simple que incorpora una colección de objetos del mismo tipo. Además incorporé un par de metodos para facilitar la incorporación de objetos.

   1:  using System.Collections.Generic;
   2:   
   3:  /// <summary>
   4:  /// Test class for ToXML extension
   5:  /// </summary>
   6:  public class Person
   7:  {
   8:    #region Constructors
   9:   
  10:    /// <summary>
  11:    /// Default constructor, need to serialize objects
  12:    /// </summary>
  13:    public Person()
  14:    {
  15:    }
  16:    public Person(string firstName, string secondName)
  17:    {
  18:      this.firstName = firstName;
  19:      this.secondName = secondName;
  20:    }
  21:    
  22:    #endregion    
  23:   
  24:    #region Fields and Properties
  25:   
  26:    private string firstName;
  27:    public string FirstName
  28:    {
  29:      get
  30:      {
  31:        return firstName;
  32:      }
  33:      set
  34:      {
  35:        firstName = value;
  36:      }
  37:    }
  38:    private string secondName;
  39:    public string SecondName
  40:    {
  41:      get
  42:      {
  43:        return secondName;
  44:      }
  45:      set
  46:      {
  47:        secondName = value;
  48:      }
  49:    }
  50:    private List<Person> childrens;
  51:    public List<Person> Childrens
  52:    {
  53:      get
  54:      {
  55:        if (childrens == null)
  56:        {
  57:          childrens = new List<Person>();
  58:        }
  59:        return childrens;
  60:      }
  61:      set
  62:      {
  63:        childrens = value;
  64:      }
  65:    }
  66:   
  67:    #endregion
  68:   
  69:    #region Methods
  70:   
  71:    /// <summary>
  72:    /// Add a children creating a new Person with parameters
  73:    /// </summary>
  74:    /// <param name="f">first name of the children</param>
  75:    /// <param name="s">second name of the children</param>
  76:    public void AddChildren(string f, string s)
  77:    {
  78:      this.Childrens.Add(new Person(f, s));
  79:    }
  80:    /// <summary>
  81:    /// Add a children creating a new Person with parameters plus current SecondName
  82:    /// </summary>
  83:    /// <param name="f">first name of the children</param>
  84:    public void AddChildren(string f)
  85:    {
  86:      this.Childrens.Add(new Person(f, this.SecondName));
  87:    }
  88:   
  89:    #endregion
  90:   
  91:  }

Finalmente para probar todo esto utilizo un metodo que crea un objeto, lo serializa y luego lo deserializa en otro objeto.

   1:      void TestUtility()
   2:      {
   3:          Person p = new Person();
   4:          
   5:          p.FirstName = "Julio";
   6:          p.SecondName = "Tentor";
   7:          p.AddChildren("Valeria", "Tentor");
   8:          p.AddChildren("Vanesa", "Tentor");
   9:          p.AddChildren("Demian");
  10:   
  11:          string xml = p.ToXml();
  12:          txtXML.Text = xml;
  13:          
  14:          Person q = xml.ConvertTo<Person>();
  15:          txtFirstName.Text = q.FirstName.ToUpper();
  16:          txtSecondName.Text = q.SecondName.ToUpper();
  17:   
  18:          StringBuilder tmp = new StringBuilder();
  19:          foreach(Person i in q.Childrens)
  20:          {
  21:              tmp.AppendLine(i.FirstName.ToUpper() + " " + i.SecondName.ToUpper());
  22:          }
  23:          txtChildrens.Text = tmp.ToString();
  24:      }

El resultado de la serialización es el siguiente:

   1:  <?xml version="1.0" encoding="utf-16"?>
   2:  <Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   3:    <FirstName>Julio</FirstName>
   4:    <SecondName>Tentor</SecondName>
   5:    <Childrens>
   6:      <Person>
   7:        <FirstName>Valeria</FirstName>
   8:        <SecondName>Tentor</SecondName>
   9:        <Childrens />
  10:      </Person>
  11:      <Person>
  12:        <FirstName>Vanesa</FirstName>
  13:        <SecondName>Tentor</SecondName>
  14:        <Childrens />
  15:      </Person>
  16:      <Person>
  17:        <FirstName>Demian</FirstName>
  18:        <SecondName>Tentor</SecondName>
  19:        <Childrens />
  20:      </Person>
  21:    </Childrens>
  22:  </Person>

El string que se obtiene al serializar el objeto se puede almacenar en un archivo, o en un campo de una base de datos.

Para finalizar acá tienen el WebSite con todo el código SerializationDemo35.zip (5,06 kb).

Espero que les sirva. 




Categorías: ASP.NET | Programacion | XML



Comments (2) -

Daniel Molina Wegener Chile

Wednesday, August 18, 2010 10:06 PM

Daniel Molina Wegener

Lamentablemente .NET no serializa objetos que tengan referencias cruzadas o circulares, se debe agregar “Ingore” en tales casos, no me ha sido muy util dada la complejidad que tienen los objetos con los que trabajo, obligandome a repensar sobre el codigo que estoy utilizando.

Prueba Argentina

Wednesday, August 18, 2010 11:22 PM

Prueba

Daniel, serializar siempre fue un problema. Especialmente cuando los objetos son complejos y por lo que estás comentando los tuyos lo son.
Como lo estas diciendo, si serializar es un requerimiento del producto la cosa esta complicada.
Lo que facilita el framework, que también se hacía en las versiones anteriroes es contar con un metodo que te brinda una versión (plana en XML) del objeto que es interesante a la hora de salvarla en un archivo o mandarla por un servicio web. Si se trata de serilizar objetos complejos hace falta un diseño y estudio de ese punto, de manera que se puedan definir los atributos necesarios en cada propiedad de los objetos.
Espero que halles una salida al trabajo que estás realizando.

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading