2012-04-23 12 views
5

Staram się zrobić bardzo prosty kawałek serializacji z XmlSerializer:Seter nie wywoływana podczas deserializacji kolekcja

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); 
     } 
    }  
} 

oszczędzania klasa ta działa dobrze, a ja się:

<?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> 

Jednak, gdy Ponownie odczytam plik, mój ustawiacz właściwości _XmlPeople nigdy nie jest wywoływany, a zatem słownik jest pusty. Wszystkie pozostałe właściwości tego obiektu otrzymują deserialized dobrze.

Czy brakuje mi czegoś oczywistego? Próbowałem różnych typów kolekcji, ale żaden z nich nie deserializacji.

EDIT: Czytaj kod:

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

jak czytasz? – Tigran

+0

Edytowałem za pomocą kodu. – GazTheDestroyer

+0

Seter nigdy nie jest wywoływany. Na tym siedzę. – GazTheDestroyer

Odpowiedz

2

Czy próbowałeś za pomocą atrybutu XmlArray?

Z Twojego przykład byłoby coś takiego:

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

EDIT:

Tutaj spróbować następującą 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; } 
} 

I nie sądzę, że będzie łatwo dodać kod do Settera na liście, więc co z tym, aby uzyskać ten słownik, kiedy faktycznie go potrzebujesz?

Jak to:

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; 
    } 
} 

ten sposób dostaniesz elementów z XML, a także mantain że Słownik same.

+0

Nie. Atrybuty oczywiście rozpoznawane podczas zapisywania, ale nadal bez obciążenia. :/ – GazTheDestroyer

+0

@GazTheDestroyer Edytował odpowiedź, aby dołączyć próbkę kodu. – Smur

+0

Wykonałem część debugowania (zobacz moją odpowiedź), ale ustawiłem odpowiedź jako poprawną, ponieważ rozwiązuje ona problem. Po prostu proszę o wyjaśnienie, na wypadek gdyby ktoś inny miał problem. – GazTheDestroyer

13

Odpowiedź dla jasności:

Zrobili niektóre debugowanie i stwierdził, że XmlSerializer nie wywołać setter dla kolekcji.

Zamiast to wywołuje getter, a następnie dodaje elementy do kolekcji zwrócony. Dlatego potrzebne jest rozwiązanie takie jak Felipe.

Powiązane problemy