Frage

Mit C # .NET 2.0, ich habe einen zusammengesetzten Datenklasse, die das [Serializable] Attribut auf es hat. Ich bin eine XMLSerializer Klasse erstellen und nebenbei, dass in den Konstruktor:

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

Ich erhalte eine Ausnahme sagen:

  

Es gab einen Fehler Typ widerspiegelt.

Innerhalb der Datenklasse gibt es ein weiteres zusammengesetztes Objekt. Gilt das auch das [Serializable] Attribut haben müssen, oder indem sie sie auf dem obersten Gegenstand hat, ist es es rekursiv innerhalb auf alle Objekte anwenden?

War es hilfreich?

Lösung

Blick auf die innere Ausnahme, Sie bekommen. Er wird Ihnen sagen, welches Feld / Eigenschaft es Probleme Serialisierung ist mit.

Sie können Felder / Eigenschaften von XML-Serialisierung ausschließen, indem sie mit dem [XmlIgnore] Attribut schmücken.

Ich glaube nicht, dass XmlSerializer verwendet das [Serializable] Attribut, so bezweifle ich, das ist das Problem.

Andere Tipps

Beachten Sie, dass serialisierte Klassen müssen Standard haben (das heißt ohne Parameter) Konstrukteuren. Wenn Sie überhaupt keinen Konstruktor haben, das ist in Ordnung; aber wenn Sie einen Konstruktor mit einem Parameter haben, müssen Sie den Standard eines hinzuzufügen.

Ich hatte ein ähnliches Problem, und es stellte sich heraus, dass der Serializer nicht zwischen zwei Klassen, die ich mit dem gleichen Namen hatte (eine war eine Unterklasse der anderen) unterscheiden konnte. Die innere Ausnahme sah wie folgt aus:

'Typen BaseNamespace.Class1' und 'BaseNamespace.SubNamespace.Class1' verwenden, um sowohl die XML-Typnamen 'Class1' aus Namespace '. Verwenden Sie XML-Attribute einen eindeutigen XML Namen und / oder Namensraum für den Typ angeben.

Wo BaseNamespace.SubNamespace.Class1 ist eine Unterklasse von BaseNamespace.Class1.

Was ich brauchte, um ein Attribut einer der Klassen zu tun, fügen Sie (ich auf die Basisklasse hinzugefügt):

[XmlType("BaseNamespace.Class1")]

Hinweis: Wenn Sie mehr Schichten von Klassen müssen Sie ein Attribut, um sie auch addieren

.

Beachten Sie auch, dass XmlSerializer keine abstrakten Eigenschaften serialisiert werden können .. meine Frage hier sehen (was ich habe die Lösung Code hinzugefügt) ..

XML-Serialisierung und Inherited Typen

Die häufigsten Gründe von mir:

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

Alle Objekte in den Serialisierungsgraphen haben serializable sein.

Da XMLSerializer eine Blackbox ist, überprüfen Sie diese Links, wenn Sie weiter in die Serialisierung debuggen ..

ändern wo XmlSerializer Ausgänge Temporäre Baugruppen

HOW TO: Debug in eine .NET XmlSerializer generierten Assembly

Wenn Sie bestimmte Attribute (zB Wörterbuch, oder jede Klasse) behandeln müssen, können Sie die IXmlSerialiable Schnittstelle, die Ihnen mehr Freiheit erlaubt auf Kosten der ausführlicheren Codierung .

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
}

Es gibt eine interessante Artikel rel="nofollow, die eine elegante Art und Weise zeigen, eine anspruchsvolle Art und Weise implementiert die XmlSerializer zu „erweitern“.


Der Artikel sagen:

  

IXmlSerializable wird in der offiziellen Dokumentation gedeckt, aber die Dokumentation gibt es nicht für den öffentlichen Gebrauch bestimmt ist und gibt keine Auskunft darüber hinaus. Dies zeigt, dass das Entwicklungsteam das Recht zu ändern, deaktivieren oder sogar vollständig entfernen diese Erweiterbarkeit Haken auf der Straße behalten wollte. Aber solange man diese Unsicherheit zu akzeptieren bereit ist, und befassen sich mit möglichen Änderungen in der Zukunft, gibt es keinen Grund auch immer Sie nicht nutzen es können.

Da dies, schlage ich vor, du bist eigene IXmlSerializable Klassen zu implementieren, um zu viel komplizierte Implementierungen zu vermeiden.

... könnte es einfach sein, unsere eigenen XmlSerializer Klasse mithilfe von Reflektion implementiert.

Ich habe entdeckt, dass die Dictionary-Klasse in .NET 2.0 nicht serialisierbar ist unter Verwendung von XML, aber serialisiert gut, wenn binärer Serialisierung verwendet wird.

fand ich eine Arbeit um hier .

Seit kurzem ist ich dies in einer Web-Referenz Teilklasse, wenn eine neue Eigenschaft hinzufügen. Die automatische generierte Klasse wurde, indem die folgenden Attribute.

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

Ich brauchte ein ähnliches Attribut mit einem Auftrag einer höher als die letzten in der automatisch generierten Sequenz hinzuzufügen und diese fixierten es für mich.

Ich dachte auch, dass das Serializable-Attribut für das Objekt sein mußte, aber es sei denn, ich bin ein komplettes Noob zu sein (ich bin in der Mitte einer Late-Night-Codierung Sitzung) die folgenden Werke aus dem 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();
        }
    }

}

Ich könnte mir vorstellen, dass die XmlSerializer Reflexion über die öffentlichen Eigenschaften verwendet wird.

Ich habe den gleichen Fehler und entdeckt, dass eine Eigenschaft des Typs IEnumerable<SomeClass> das Problem war. Es scheint, dass IEnumerable nicht direkt serialisiert werden.

Stattdessen könnte man List<SomeClass> verwenden.

Ich hatte eine Situation, wo der Orden das gleiche für zwei Elemente in einer Reihe war

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

.... einige Code ...

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

Wenn ich den Code geändert, um die Reihenfolge durch einen für jede neue Property in der Klasse zu erhöhen, wird der Fehler ging weg.

Beachten Sie auch, dass Sie nicht Benutzeroberfläche steuert und dass jedes Objekt serialisiert werden können wollen Sie passieren in die Zwischenablage serializable sein muss sonst kann es nicht über zu anderen Prozessen übergeben werden.

Ich habe mit der NetDataSerialiser Klasse serialise meine Domain-Klassen. NetDataContractSerializer Klasse .

Die Domain Klassen geteilt werden zwischen Client und Server.

[System.Xml.Serialization.XmlElementAttribute ( "strFieldName", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

// Or

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

Ich hatte das gleiche Problem und in meinem Fall hatte die Aufgabe, ein Readonlycollection. Eine Sammlung muss Add-Methode sein serializable implementieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top