| 

.NET C# Java Javascript Exception

4
Hallo,

Evtl. könnt ihr mir den Tag retten. Ich versuche ein Objekt welches eine ObservableCollection implementiert hat zu serialisieren.
Mein Problem ist es, dass ich im XML String xsi:type="AObject" im Element habe.

<AObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<LogicalID>ABC</ LogicalID >
<TestObjectChildList>
<BaseObject xsi:type="AObject">
<LogicalID>qwerz</LogicalID>
</BaseObject>
<BaseObject xsi:type="AObject">
<LogicalID>qwerz1</LogicalID>
</BaseObject>
</AObject>


Aber ich möchte:

<AObject> 
<TestObjectChildList>
<AObject>….
</TestObjectCildList>
</AObject>

Dies funktioniert, wenn ich im BaseObject bei der Collection das XMLArrayList(„AObject“) setze. Setze ich zusätzlich auch das XMLArrayList(„BObject“), funktioniert dies nicht mehr, wenn ich es versuche zu serialisieren.

BaseObject testObject = this.rootElementListView.SelectedItem as BaseObject;
xmlSerializer = new XmlSerializer(testObject.GetType());

Dann bekomme ich die folgenden Execption:
"The XML element 'LogicalID' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element."

Wie kriege ich dies zum funktionieren

[XmlInclude(typeof(AObject))] 
public class AObject : BaseObject
{
[XmlElement]
public override string LogicalID { get; set; }

public override ObservableCollection<BaseObject> TestObjectChildList { get; set; }

/** andere Properties als im BObject**/
}
}

XmlInclude(typeof(BObject))]
public class BObject : BaseObject
{
[XmlElement]
public override string LogicalID { get; set; }

public override ObservableCollection<BaseObject> TestObjectChildList { get; set; }

/** andere Properties als im AObject **/
}
}

[Serializable]
public abstract class BaseObject
{
private string logicalID;
public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string someLogicalId)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(someLogicalId));
}
}

public virtual string LogicalID
{
get
{
return logicalID;
}
set
{
logicalID = value;
OnPropertyChanged(logicalID);
}
}


public virtual ObservableCollection<BaseObject> TestObjectChildList { get; set; }
}


Evtl. von wichtigkeit die Objekte werden nicht gemischt. D.h. es gibt nur AObjekte mit Collections von AObjekten oder BObjecte mit Collection von BObjekten

Gruss und vielen Dank
Daniele
03.01.2012
CodingMan 168 5
3 Antworten
2
Noch ein anderer Ansatz:

Du überschreibst in AObject und BObject merkwürdigerweise die Property TestObjectChildList. Brauchst Du überhaupt Polymorphismus für diese Property? Wenn nicht, wirf sie einfach aus der Basisklasse raus und schreibe in AObject und BObject jeweils den passenden Typ für die Property hin. Falls Du den Polymorphismus tatsächlich brauchst, könntest Du versuchen, die mit BaseObject typisierte Liste mit XmlIgnore aus de Serialisierung herauszunehmen und in AObject und BObject nochmal zusätzliche read-only-Properties vom passenden Typ hinzuzufügen, die sich auf die Property aus der Basisklasse abstützen (und dann natürlich nicht automatisch implementiert werden können).
03.01.2012
Matthias Hlawatsch 13,2k 4 9
Hi Floyd, kannst Du den Edit bitte wieder rückgängig machen? Das sind zwei völlig verschiedene und voneinander unabhängige Antworten, und ich möchte weder Bewertungen noch Kommentare dazu vermengt sehen, nur weil sie vom selben Autor stammen.
Matthias Hlawatsch 03.01.2012
Hab's jetzt selbst gemacht. Bitte auch so lassen.
Matthias Hlawatsch 03.01.2012
2
Was .NET da macht, ist zunächst mal korrekt. Mit dem XmlArrayListAttribute kannst Du bestimmen, wie das XML-Element heißt, das für die einzelnen Elemente der Liste verwendet wird. Wenn es nicht gesetzt ist, leitet .NET es aus dem Typen des Arrays ab. Dort typabhängig verschiedene Namen zu verwenden, unterstützt das Attribut aber nicht.

Versuche mal, die Dinge aus XML-Sicht zu sehen und überlege Dir, wie ein XSD-Schema aussehen würde, das an dieser Stelle verschiedene Element-Namen zulassen würde. Du landest dann ziemlich sicher bei einer XSD-Choice. Von daher meine Empfehlung: schau Dir die MSDN-Doku zum XmlChoiceIdentifierAttribute an und insbesondere unter Hinweise das zweite Szenario. Das scheint mir einigermaßen ähnlich zu Deinem Fall zu sein, vor allem, was das Aussehen des XMLs angeht. Damit könnte es gehen - getestet habe ich es aber nicht.
03.01.2012
Matthias Hlawatsch 13,2k 4 9
0
Hallo Matthias,

Danke für deine Hilfe. Habe es mit deiner letzten Antwort hingekriegt, so wie ich es wollte. Hätte mir auch selbst in den Sinn kommne sollen, aber ich war so festgefahren das ich den Wald vor lauter Bäumen nicht mehr gesehen habe. :)

Gruss und Danke
Daniele

Hier noch die Lösung
[XmlIgnore] 
public override ObservableCollection<BaseObject> TestObjectChildList { get; set; }

[XmlArrayItem(Type=typeof(AObject),ElementName="AObject")]
public ObservableCollection<BaseObject> AObjectList
{
get
{
return TestObjectChildList;
}
}
04.01.2012
CodingMan 168 5

Stelle deine .net-Frage jetzt!