none
Error desearilizar archivo XML que contiene un List Of RRS feed

  • Pregunta

  • Muy buenas tardes;

    No se que pueda ser el error, pero al tratar de desearilizar un archivo XML que contiene una lista falla. Voya mostrar la clase que se serializa en formato XML:

    Option Strict On
    Option Explicit On
    Imports CivilSoft.Enumeraciones
    Imports System.Configuration
    Imports System.Xml.Serialization
    
    ''' <summary>
    ''' Clase base para las configuraciones o preferencias del usuario.
    ''' </summary>
    <XmlRoot("UserConfig")>
    Public Class UserSettings
    
    #Region "Variables"
    
    #Region "General"
    
        Private _unidades As Enum_SistemaUnidades
        Private _cantDec As Enum_CantidadDecimales
        Private _gravedad_ms2 As Decimal
    
    #End Region
    
    #Region "Análisis"
    
        Private _teoriasCalculo As New List(Of Enum_TeoriasCalculo)
        Private _factorsegFS As Decimal
        Private _calcular_qneta As Boolean
        Private _tablaNɣ_Ter As QultTerzaghi.TeoriaNγ
    
    #End Region
    
    #End Region
    
    #Region "Constructor"
    
        ''' <summary>
        ''' Constructor predeterminado de la clase.
        ''' </summary>
        Public Sub New()
    
            'General.
            '--------
            '
            'Sistema de unidades.
            _unidades = Enum_SistemaUnidades.kN_m
            'Decimales de trabajo.
            _cantDec = Enum_CantidadDecimales.Dos
            'Gravedad en m/s².
            _gravedad_ms2 = 9.8D
    
            'Análisis.
            '----------
            '
            'Lista de teorías de cálculo.
            _teoriasCalculo.AddRange({Enum_TeoriasCalculo.Terzaghi, Enum_TeoriasCalculo.Meyerhof})
            'Factor de seguridad.
            _factorsegFS = 3D
            'Calcular capacidad de carga admisible neta.
            _calcular_qneta = False
            'Tabla usada para calcular Nɣ por la teoría de Terzgahi.
            _tablaNɣ_Ter = QultTerzaghi.TeoriaNγ.Terzaghi
    
        End Sub
    
    #End Region
    
    #Region "Propiedades"
    
    #Region "General"
    
        ''' <summary>
        ''' Sistema de unidades para trabajar con los diferentes tipos de unidades.
        ''' </summary>
        ''' <returns></returns>
        <XmlElement(ElementName:="Unidades")>
        Public Property Unidades As Enum_SistemaUnidades
            Get
                Return _unidades
            End Get
            Set(value As Enum_SistemaUnidades)
                _unidades = value
            End Set
        End Property
    
        ''' <summary>
        ''' Cantidad de decimales de trabajo.
        ''' </summary>
        ''' <returns></returns>
        <XmlElement(ElementName:="CantDecimales")>
        Public Property CantDecimales As Enum_CantidadDecimales
            Get
                Return _cantDec
            End Get
            Set(value As Enum_CantidadDecimales)
                _cantDec = value
            End Set
        End Property
    
        ''' <summary>
        ''' Gravedad en unidades de m/s².
        ''' </summary>
        ''' <returns></returns>
        <XmlElement(ElementName:="Gravedad_ms2")>
        Public Property Gravedad_ms2 As Decimal
            Get
                Return _gravedad_ms2
            End Get
            Set(value As Decimal)
                _gravedad_ms2 = value
            End Set
        End Property
    
    #End Region
    
    #Region "Análisis"
    
        ''' <summary>
        ''' Lista de teorías de cálculo para calcular la capacidad de carga.
        ''' </summary>
        ''' <returns></returns>
        <XmlArray("ListTeorias")>
        <XmlArrayItem("Teoria")>
        Public Property TeoriasCalculo As List(Of Enum_TeoriasCalculo)
            Get
                Return _teoriasCalculo
            End Get
            Set(value As List(Of Enum_TeoriasCalculo))
                _teoriasCalculo = value
            End Set
        End Property
    
        ''' <summary>
        ''' Factor de segurdiada FS usado para calcular la capacidad de carga admisible.
        ''' </summary>
        ''' <returns></returns>
        <XmlElement(ElementName:="FS")>
        Public Property FactorSeguridad As Decimal
            Get
                Return _factorsegFS
            End Get
            Set(value As Decimal)
                _factorsegFS = value
            End Set
        End Property
    
        ''' <summary>
        ''' Indica si se debe calcular la capacidad de carga admisible neta.
        ''' </summary>
        ''' <returns></returns>
        <XmlElement(ElementName:="Calc_qneta")>
        Public Property Calcular_qneta As Boolean
            Get
                Return _calcular_qneta
            End Get
            Set(value As Boolean)
                _calcular_qneta = value
            End Set
        End Property
    
        ''' <summary>
        ''' Tabla para calcular el valor del factor de capacidad de carga Nɣ para la teoría de Terzaghi.
        ''' </summary>
        ''' <returns></returns>
        <XmlElement(ElementName:="TableNɣ_Ter")>
        Public Property TablaNɣ_Ter As QultTerzaghi.TeoriaNγ
            Get
                Return _tablaNɣ_Ter
            End Get
            Set(value As QultTerzaghi.TeoriaNγ)
                _tablaNɣ_Ter = value
            End Set
        End Property
    
    #End Region
    
    #End Region
    
    #Region "Métodos"
    
    #End Region
    
    End Class

    El error se genera cuando intento obtener el Listado de teorías en esta propiedad:

        ''' <summary>
        ''' Lista de teorías de cálculo para calcular la capacidad de carga.
        ''' </summary>
        ''' <returns></returns>
        <XmlArray("ListTeorias")>
        <XmlArrayItem("Teoria")>
        Public Property TeoriasCalculo As List(Of Enum_TeoriasCalculo)
            Get
                Return _teoriasCalculo
            End Get
            Set(value As List(Of Enum_TeoriasCalculo))
                _teoriasCalculo = value
            End Set
        End Property

    Pues, por alguna extraña razón me devuelve un listado con los valores por defecto del constructor más las que le he asignado antes de serializar dicha clase en un documento XML.

    Los métodos que uso para serializar y desearilizar son los siguientes:

        ''' <summary>
        ''' Crea un archivo de tipo Xml en la ruta especificada, serializando un tipo de objeto.
        ''' </summary>
        ''' <typeparam name="T">Tipo de objeto que se desea serializar.</typeparam>
        ''' <param name="objeto">Instancia del objeto que se desea serializar.</param>
        ''' <param name="path">Ruta donde se creara el archivo xml. Tener en cuenta que dicha ruta debe tener permisos de
        ''' escritura, ya que sino es así, éste método retornará una excepción.</param>
        Private Sub SerializeXml(Of T)(ByVal objeto As T, ByVal path As String)
    
            'Se encapsula dentro de un Try, para capturar las posibles excepciones.
            Try
    
                'Serializador de tipo XML.
                Dim serializador As New Serialization.XmlSerializer(GetType(T))
                'Flujo de datos para crear el archivo serializado.
                Dim fs As New FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)
    
                'Se serializa el archivo con la secuencia indicada.
                serializador.Serialize(fs, objeto)
    
                'Cerramos el flujo.
                fs.Close()
    
            Catch ex As Exception
    
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Lee un archivo XML desde un rura especificada, y lo convierte a un tipo de objeto determinado.
        ''' </summary>
        ''' <typeparam name="T">Tipo de objeto que se convierte el archivo desearilizado.</typeparam>
        ''' <param name="path">Ruta donde está el archivo xml. Tener en cuenta que dicha ruta debe tener permisos de
        ''' lectura, ya que sino es así, éste método retornará una excepción.</param>
        Private Function DeserializeXml(Of T)(ByVal path As String) As T
    
            'Se encapsula dentro de un Try, para capturar las posibles excepciones.
            Try
    
                'Serializador de tipo XML.
                Dim serializador As New Serialization.XmlSerializer(GetType(T))
                'Flujo de datos para crear el archivo serializado. De igual crearmo un lector XML.
                Dim fs As New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
                Dim reader As XmlReader = XmlReader.Create(fs)
                'Desearilizamos el archivo convirtiéndolo al objeto especificado.
                Dim ins As T
                ins = CType(serializador.Deserialize(reader), T)
    
                'Cerramos el flujo.
                fs.Close()
    
                'Finalmente, se retorna el objeto desearilizado.
                Return ins
    
            Catch ex As Exception
    
                Return Nothing
    
            End Try
    
        End Function

    Muestro un ejemplar del archivo XML que se genera, que por lo visto lo observo correctamente.

    <?xml version="1.0"?>
    <UserConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Unidades>kN_m</Unidades>
      <CantDecimales>Dos</CantDecimales>
      <Gravedad_ms2>9.8</Gravedad_ms2>
      <ListTeorias>
        <Teoria>Terzaghi</Teoria>
        <Teoria>Meyerhof</Teoria>
      </ListTeorias>
      <FS>3</FS>
      <Calc_qneta>false</Calc_qneta>
      <TableNɣ_Ter>Terzaghi</TableNɣ_Ter>
    </UserConfig>

    Si me he hecho explicar ¿sabe a que se debe este pequeño error?. Como comenté, sólo falla al tratar el List (Of Enum_TeoriasCalculo).

    Voy a mostrar cuando hago el BreakPoint al desearilizar el archivo XML mostrado previamente, pues en la propiedad,

    Public Property TeoriasCalculo As List(Of Enum_TeoriasCalculo)

    me debería de devolver {Terzaghi, Meyerhof}, pero lo que hace es devolverme {Terzaghi, MeyerhofT, Terzaghi, Meyerhof}, es decir duplica la lista de teorías. Muestro la imagen del BreakPoint:

    AAgradezco me puedan orientar, pues sólo el problema es cuando trabajo con un List Of.


    Harold Alonso Quintero Pineda Ingeniero Civil Universidad Francisco de Paula Santander Ocaña Correo: haroldpineda1401@outlook.com Cel: 3158700970

    sábado, 27 de enero de 2018 23:11

Todas las respuestas

  • Hola Harold Quintero Pineda

    Con respecto a tu consulta, recomiendo ir al siguiente enlace que puede serte útil.

    https://msdn.microsoft.com/es-es/library/system.xml.serialization.xmlserializer(v=vs.110).aspx

    Quedamos al pendiente de cualquier comentario de tu parte.

    Saludos Cordiales.

    Gracias por usar los foros de MSDN.

    Pablo Rubio
     _____

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde. 

    Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft.  

    Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft.

    lunes, 29 de enero de 2018 18:25
    Moderador
  • Muy buenas tardes;

    He leído el docuemnto, y dice que la clase XmlSerializer no serializa ni deserealiza un ArrayList ni List(Of), está última con la que estoy teniendo problemas. Podría usted ayudarme indicándome ¿cuál es entonces la alternativa para este caso?, pues tengo un Enum, y la propiedad que deseo serializar en un documento XML es una lista de valores que contiene dicho Enum; ¿cual es la mejor alternativa?

    Muchas gracias.


    Harold Alonso Quintero Pineda Ingeniero Civil Universidad Francisco de Paula Santander Ocaña Correo: haroldpineda1401@outlook.com Cel: 3158700970

    lunes, 29 de enero de 2018 18:36