Pregunta

El Uso De C# .NET 2.0, tengo un compuesto de datos de la clase que tiene el [Serializable] atributo.Estoy creando un XMLSerializer clase y que pasa en el constructor:

XmlSerializer serializer = new XmlSerializer(typeof(DataClass));

Me estoy haciendo una excepción diciendo:

Hubo un error reflejando tipo.

Dentro de la clase de datos hay otro objeto compuesto.¿Esto también se necesita tener el [Serializable] atributo, o por tener en la parte superior del objeto, lo hace de forma recursiva se aplican a todos los objetos que hay dentro?

¿Fue útil?

Solución

Mira en el interior de la excepción de que usted está recibiendo.Le dirá que el campo de la propiedad, que está teniendo problemas para serializar.

Puede excluir los campos y propiedades de la serialización xml mediante la decoración con el [XmlIgnore] atributo.

No creo que XmlSerializer utiliza el [Serializable] atributo, por lo que dudo que sea el problema.

Otros consejos

Recuerde que serializa las clases deben tener por defecto (es decir,sin parámetros) de los constructores.Si usted no tiene ningún constructor en todos, eso está bien;pero si usted tiene un constructor con un parámetro, usted tendrá que agregar el de por defecto también.

He tenido un problema similar, y resultó que el serializador no podía distinguir entre las 2 clases que he tenido con el mismo nombre (uno era una subclase de la otra).El interior de la excepción se veía así:

'Tipos De BaseNamespace.Class1' y 'BaseNamespace.SubNamespace.Class1 " tanto el uso del XML nombre del tipo, 'Class1', desde el espacio de nombres ".El uso de atributos XML para especificar un único nombre XML y/o espacio de nombres para el tipo.

Donde BaseNamespace.SubNamespace.Class1 es una subclase de BaseNamespace.Class1.

Lo que necesitaba hacer era añadir un atributo a una de las clases (he añadido a la base de la clase):

[XmlType("BaseNamespace.Class1")]

Nota:Si usted tiene más capas de las clases que necesita para añadir un atributo a ellos también.

También ser conscientes de que XmlSerializer no se puede serializar propiedades abstractas..Ver a mi pregunta aquí (que he añadido a la solución de código)..

La Serialización XML y Heredado de los Tipos de

Razones más comunes por mí:

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members

Todos los objetos de la serialización gráfico tiene que ser serializable.

Desde XMLSerializer es una caja negra, visite estos enlaces si desea depurar aún más en el proceso de serialización..

Cambiando donde XmlSerializer Salidas Temporales de Asambleas

CÓMO:Depurar en un .NET XmlSerializer Ensamblado Generado

Si usted necesita para manejar atributos específicos (es decir,De diccionario, o de cualquier clase), puede implementar el IXmlSerialiable la interfaz, lo que le permitirá más libertad en el costo de más detallado de codificación.

public class NetService : IXmlSerializable
{
    #region Data

        public string Identifier = String.Empty;

        public string Name = String.Empty;

        public IPAddress Address = IPAddress.None;
        public int Port = 7777;

    #endregion

    #region IXmlSerializable Implementation

        public XmlSchema GetSchema() { return (null); }

        public void ReadXml(XmlReader reader)
        {
            // Attributes
            Identifier = reader[XML_IDENTIFIER];
            if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
            if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
        }

        public void WriteXml(XmlWriter writer)
        {
            // Attributes
            writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
            writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
            writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
        }

        private const string XML_IDENTIFIER = "Id";

        private const string XML_NETWORK_ADDR = "Address";

        private const string XML_NETWORK_PORT = "Port";

    #endregion
}

Hay un interesante artículo, que muestran una forma elegante, implementa una manera sofisticada para "extender" la clase XmlSerializer.


El artículo dice:

IXmlSerializable está cubierto en la documentación oficial, pero la documentación de los estados no está pensada para el uso público y no se proporciona ninguna información más allá de eso.Esto indica que el equipo de desarrollo quería reserva el derecho a modificar, desactivar, o incluso eliminar completamente esta extensibilidad gancho hacia abajo de la carretera.Sin embargo, siempre y cuando usted está dispuesto a aceptar la incertidumbre y el trato con los posibles cambios en el futuro, no hay ninguna razón usted no puede tomar ventaja de ello.

Debido a esto, sugiero que para implementar tu propio IXmlSerializable las clases, con el fin de evitar demasiado complicado implementaciones.

...que podría ser sencillo implementa nuestra costumbre XmlSerializer clase de uso de la reflexión.

He descubierto que la clase Dictionary .Net 2.0 no es serializable con XML, pero serializa bien cuando la serialización binaria se utiliza.

He encontrado un trabajo en torno a aquí.

Recientemente recibí esto en una web de referencia de la clase parcial cuando se agrega una nueva propiedad.El auto de la clase generada fue la adición de los siguientes atributos.

    [System.Xml.Serialization.XmlElementAttribute(Order = XX)]

Tuve que agregar un similar atributo con un pedido superior a la última en el auto genera la secuencia y esta arreglado para mí.

Yo también pensaba que el atributo Serializable tenía que ser en el objeto, pero a menos que soy un completo noob (yo estoy en el medio de una noche de codificación de sesión) las siguientes obras de la SnippetCompiler:

using System;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.Xml.Serialization;

public class Inner
{
    private string _AnotherStringProperty;
    public string AnotherStringProperty 
    { 
      get { return _AnotherStringProperty; } 
      set { _AnotherStringProperty = value; } 
    }
}

public class DataClass
{
    private string _StringProperty;
    public string StringProperty 
    { 
       get { return _StringProperty; } 
       set{ _StringProperty = value; } 
    }

    private Inner _InnerObject;
    public Inner InnerObject 
    { 
       get { return _InnerObject; } 
       set { _InnerObject = value; } 
    }
}

public class MyClass
{

    public static void Main()
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
            TextWriter writer = new StreamWriter(@"c:\tmp\dataClass.xml");
            DataClass clazz = new DataClass();
            Inner inner = new Inner();
            inner.AnotherStringProperty = "Foo2";
            clazz.InnerObject = inner;
            clazz.StringProperty = "foo";
            serializer.Serialize(writer, clazz);
        }
        finally
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }

}

Me imagino que la clase XmlSerializer es el uso de la reflexión sobre las propiedades públicas.

Acabo de recibir el mismo error y descubrió que una propiedad de tipo IEnumerable<SomeClass> era el problema.Parece que IEnumerable no se puede serializar directamente.

En lugar de eso, uno podría usar List<SomeClass>.

Tuve una situación en la que el Orden fue el mismo para los dos elementos en una fila

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")]

....algunas código ...

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")]

Cuando he cambiado el código para incrementar la orden de uno en uno para cada nueva Propiedad en la clase, el error se fue.

También tenga en cuenta que usted no se puede serializar controles de interfaz de usuario y que cualquier objeto en el que desea pasar en el portapapeles deben ser serializables de lo contrario, no puede ser transmitido a través de otros procesos.

He estado usando el NetDataSerialiser clase a serialise mis clases de dominio. NetDataContractSerializer Clase.

El dominio de las clases son compartidos entre el cliente y el servidor.

[Sistema.Xml.La serialización.XmlElementAttribute("strFieldName", Forma = Sistema.Xml.Esquema.XmlSchemaForm.Sin calificar)]

//O

[XmlIgnore] string [] strFielsName {get;set;}

Yo tenía el mismo problema y en mi caso, el objeto tenía un ReadOnlyCollection.Una colección debe aplicar el método de adición de ser serializable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top