Tips.cl

C#

Deserializar/Serializar un listado de objetos con XmlArray, XmlArrayElement, XmlElement

by Rodrigo Olivares on Jun.18, 2009, under C#, VB.NET, Xml

Cuando usamos serialización es común encontrarse con estilos diferentes en la definición de esquemas para los archivos XML (sobre todo si tomamos servicios generados por otros equipos de trabajo). Por ejemplo, tenemos un XML que contiene información de libros, que contempla un autor con un listado de libros que él ha escrito. Entonces una forma de representar el XML puede ser:

<biblioteca>
    <autores>
        <autor nombre="" apellido="">
          <libros>
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
          </libros>
        </autor>
     </autores>
</biblioteca>

Entonces nuestras clases DatosAutor y DatosLibro podrían ser definidas de la siguiente forma:

<XmlRoot("autor")> _
Public Class DatosAutor
 
    Private _apellido As String
    <XmlAttribute("apellido")> _
    Public Property Apellido() As String
        Get
            Return _apellido
        End Get
        Set(ByVal value As String)
            _apellido = value
        End Set
    End Property
 
    Private _nombre As String
    <XmlAttribute("nombre")> _
    Public Property Nombre() As String
        Get
            Return _nombre
        End Get
        Set(ByVal value As String)
            _nombre = value
        End Set
    End Property
 
    Private _libros As List(Of DatosLibro)
    <XmlArray("libros"), XmlArrayItem("libro")> _
    Public Property Libros() As List(Of DatosLibro)
        Get
            Return _libros
        End Get
        Set(ByVal value As List(Of DatosLibro))
            _libros = value
        End Set
    End Property
 
End Class
 
Public Class DatosLibro
 
    Private _ISBN As String
    <XmlAttribute()> _
    Public Property ISBN() As String
        Get
            Return _ISBN
        End Get
        Set(ByVal value As String)
            _ISBN = value
        End Set
    End Property
 
    Private _nombre As String
    <XmlAttribute("nombre")> _
    Public Property Nombre() As String
        Get
            Return _nombre
        End Get
        Set(ByVal value As String)
            _nombre = value
        End Set
    End Property
 
End Class

Ahora es probable que el XML pueda estar formateado de esta forma, o alguna mezcla con la anterior (noten la diferencia con la forma de agrupar los elementos “libro”):

<biblioteca>
        <autor nombre="" apellido="">
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
        </autor>
        <autor nombre="" apellido="">
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
            <libro nombre="" ISBN="" />
        </autor>
</biblioteca>

Para ello podremos usar la propiedad XmlElement indicando el nombre del elemento que se agregará al listado.

    Private _libros As List(Of DatosLibro)
    <XmlElement("libro")> _
    Public Property Libros() As List(Of DatosLibro)
        Get
            Return _libros
        End Get
        Set(ByVal value As List(Of DatosLibro))
            _libros = value
        End Set
    End Property

Nota 1 : el ejemplo está aplicado solamente al nivel anidado de la clase DatosAutor, pero que perfectamente es aplicable al nivel más alto del listado de “Autores”.

Nota 2 : la propiedad XmlRoot() está definida para este caso para la clase DatosAutor, pero para la clase DatosLibro no se ha especificado. Esto es debido a que por defecto la deserialziación tomará el nodo especificado por XmlArrayItem (o XmlElement) y lo convertirá al tipo definido en el listado, no importando el nombre de la clase.

Nota 3 :Noten que para la propiedad ISBN del libro no tiene definido el nombre del atributo, esto significa que el atributo en el XML tiene el mismo nombre que el definido en la clase, en los otros cases debimos especificar el nombre debido a que en el Xml se usa lowercase.

Nota 4 :si no se especifica lo contrario la serialización asumirá que el atributo definido en la clase “calza” con un nodo dentro del XML definido con el mismo nombre. Si se especifica XmlAttribute(), se indicará que el atributo definido calza con un atributo xml con el mismo nombre que la propiedad.

Nota 5 : es posible redefinir los atributos, como por ejemplo XmlRoot para clases ya creadas, muy útil cuando queremos reutilizar una clase para la cual solamente cambia el XmlRoot definido.

2 Comentarios más...

Iterar sobre las secciones de nuestro web.config

by Rodrigo Olivares on Jun.17, 2009, under C#, VB.NET

Si estás a la tarea de generar tu propia sección de configuración en el archivo tu app.config o web.config, es útil que tu implementación verifique la existencia de su sección de configuración, ya sea en el web.config o en el .config relativo a la aplicación en donde la deseas usar.

Cuando busqué información sobre iterar sobre secciones, me costó un poco encontrar, finalmente di con este post donde de pasada solucionaron básicamente mi problema.

    Dim configFile As Configuration
    ''Open app.config or web.config file
    If (HttpContext.Current Is Nothing) Then
       configFile = WebConfigurationManager.OpenWebConfiguration("~")
    Else
       configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
    End If

En nuestra aplicación tenemos una sección de configuración que hereda de ConfigurationSection llamada ConfiguracionGraficos. Entonces una manera de que la aplicación busque su entrada de configuración sería la siguiente :

    Imports System.Configuration.ConfigurationManager
    Imports System.Configuration
    Imports System.Web.Configuration
 
    ' Get the mapped configuration file.
    Dim config As Configuration _
          = WebConfigurationManager.OpenWebConfiguration("~")
 
    For Each section As ConfigurationSection In config.Sections
       If TypeOf (section) Is ConfiguracionGraficos Then
          _configuraciones = DirectCast(section, ConfiguracionGraficos)
          Exit Sub
       End If
    Next
    Throw New Exception("No se ha definido la entrada de configuracion")
2 Comentarios :, , , , , , , , más...

Acceder a una propiedad dinámicamente

by abraham on Jun.05, 2009, under C#

Constantemente se nos ha ocurrido construir una aplicación dinámica que acceda a las propiedades de un objeto de manera tal que no sea necesario conocer de antemano el nombre de estas.

La solución en .NET es reflection, parte del class library del framework 2.0 que nos permite acceder a estas, además de otras cosas, como actualizar los valores de los miembros de las clases como propiedades, variables públicas (fields), obtener los constructores, etc..

vasta con hacer el siguiente import:
using System.Reflection;
y ya tenemos disponible mediante <objeto>.getType() un conjunto de propiedades y métodos para acceder.

Ejemplo:

public class Foo {
private string var;

public string Var {
get {
return var;
} set {
var= value;

}
}
}

Usado System.Reflection podemos acceder a la propiedad Var de la clase Foo de la siguiente forma:

Foo myObjeto = new Foo();
string value = (string)myObjeto .GetType().InvokeMember(”Var“, BindingFlags.GetProperty,     null,myObjeto, new object[] { });

Donde  “Var” es la propiedad accedida dinámicamente, BindingFlags.GetProperty es la acción que se está realizando, en este caso Obtener Propiedad (hay para otros miembros y asignaciones)

Hay otras formas más cortas pero menos dinámicas por ejemplo:

string value = myObjeto .GetType().GetProperty(“Var”).GetValue(myObjeto , new object[] { })

Si se fijan “Var” está entre comillas lo que significa que puede ser cualquier string, una constante, variable o una key en el archivo de configuración.

6 Comentarios :, , más...

Autoincrementar número de versión en .NET

by MigueliTUX on Mar.25, 2009, under C#, VB.NET

Si necesitas incrementar el numero de version en .net

debes

hacer doble clic en My Project

luego editar el archivo AssemblyInfo.vb

remplazar     <Assembly: AssemblyVersion(”1.0.0.0″)>
por              <Assembly: AssemblyVersion(”1.0.*”)>

6 Comentarios :, , , más...

Eliminar el VIEWSTATE en C#

by MigueliTUX on Feb.03, 2009, under C#, Windows

protected override void Render(HtmlTextWriter writer)
{
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlWriter);
string html = stringWriter.ToString();
int endPoint;
int startPoint = html.IndexOf(”<input type=\”hidden\” name=\”__VIEWSTATE\”");
if (startPoint >= 0)
{
endPoint = html.IndexOf(”/>”, startPoint) + 2;
html = html.Remove(startPoint, endPoint - startPoint);
}
writer.Write(html);
}

No es muy elegante pero funciona

4 Comentarios :, más...

Buscas algun tips?

Busca aquí:

contactate con nosotos contacto@tips.cl

Visita nuestras Web amigas!

Web Amigas...