2012-04-23 3 views
5

Ich versuche, ein sehr einfaches Stück Serialisierung mit XmlSerializer zu tun:Setter nicht aufgerufen, wenn Deserialisieren Sammlung

public struct XmlPerson 
{ 
    [XmlAttribute] public string Id { get; set; } 
    [XmlAttribute] public string Name { get; set; } 
} 

public class GroupOfPeople 
{ 
    private Dictionary<string, string> _namesById = new Dictionary<string, string>(); 

    //pseudo property for serialising dictionary to/from XML 
    public List<XmlPerson> _XmlPeople 
    { 
     get 
     { 
      var people = new List<XmlPerson>(); 
      foreach (KeyValuePair<string, string> pair in _namesById) 
       people.Add(new XmlPerson() { Id = pair.Key, Name = pair.Value }); 

      return people; 
     } 
     set 
     { 
      _namesById.Clear(); 
      foreach (var person in value) 
       _namesById.Add(person.Id, person.Name); 
     } 
    }  
} 

Speichern dieser Klasse funktioniert gut, und ich bekomme:

<?xml version="1.0" encoding="utf-8"?> 
<GroupOfPeople xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <_XmlPeople> 
     <XmlPerson Id="person1" Name="Fred" /> 
     <XmlPerson Id="person2" Name="Bill" /> 
     <XmlPerson Id="person3" Name="Andy" /> 
     <XmlPerson Id="person4" Name="Nagesh" /> 
    </_XmlPeople> 
</GroupOfPeople> 

Wenn jedoch Ich lese die Datei erneut ein, mein _XmlPeople-Eigenschaftensetter wird nie aufgerufen, und daher ist das Wörterbuch leer. Alle anderen Eigenschaften dieses Objekts werden deserialisiert.

Fehle ich etwas offensichtlich? Ich habe verschiedene Sammeltypen ausprobiert, aber keiner von ihnen deserialisiert.

EDIT: Lesen Sie den Code ein:

try 
{ 
    using (var stream = new StreamReader(itemPath)) 
    { 
     var xml = new XmlSerializer(typeof(GroupOfPeople)); 
     GroupOfPeople item = (GroupOfPeople)xml.Deserialize(stream); 
    } 
} 
//snip error stuff 
+0

Wie liest du? – Tigran

+0

Habe mit Code bearbeitet. – GazTheDestroyer

+0

Der Setter wird nie aufgerufen. Ich habe einen Haltepunkt darauf gesetzt. – GazTheDestroyer

Antwort

2

Haben Sie versucht, die XmlArray Attribut?

Mit Ihrem Beispiel wäre es so etwas wie dieses:

[XmlArray] 
[XmlArrayItem(ElementName="XmlPerson")] 
public List<XmlPerson> XmlPeople 

EDIT:

Hier versuchen die folgende Struktur:

public struct XmlPerson 
{ 
    [XmlAttribute] public string Id { get; set; } 
    [XmlAttribute] public string Name { get; set; } 
} 


public class GroupOfPeople 
{ 
    [XmlArray] 
    [XmlArrayItem(ElementName="XmlPerson")] 
    public List<XmlPerson> XmlPeople { get; set; } 
} 

Ich glaube nicht, es wird Es ist einfach, Code zum Setter der Liste hinzuzufügen, also was ist mit dem Wörterbuch, wenn du es wirklich brauchst?

So:

private Dictionary<string, string> _namesById; 

public Dictionary<string, string> NamesById 
{ 
    set { _namesById = value; } 
    get 
    { 
     if (_namesById == null) 
     { 
      _namesById = new Dictionary<string, string>(); 

      foreach (var person in XmlPeople) 
      { 
       _namesById.Add(person.Id, person.Name); 
      } 
     } 

     return _namesById; 
    } 
} 

diese Weise werden Sie die Elemente aus dem XML erhalten und wird mantain auch, dass Wörterbuch von Ihnen.

+0

Nein. Attribute offensichtlich beim Speichern erkannt, aber immer noch nicht geladen. :/ – GazTheDestroyer

+0

@GazTheDestroyer Bearbeitete die Antwort, um ein Codebeispiel einzuschließen. – Smur

+0

Habe schon ein paar Debugging gemacht (siehe meine Antwort), aber habe deine Antwort richtig eingestellt, da sie das Problem löst. Setzen Sie einfach meine Antwort für Klarheit, falls jemand anderes das Problem hat. – GazTheDestroyer

13

Antwort für Klarheit:

Haben einige Debug und gefunden getan, dass XmlSerializer nicht den Setter für eine Sammlung nicht nennen.

Stattdessen ruft die Getter, und fügt dann Elemente zur Sammlung zurück. Daher ist eine Lösung wie die von Felipe notwendig.

Verwandte Themen