Błąd przy deserializacji XML z DataContractSerializer - typ generyczny

0

Walczę z deserializację tego co przysyła jeden program. Przy próbie deserializacji obiektu otrzymuję taki błąd:
System.Runtime.Serialization.SerializationException : Błąd w wierszu 1 w pozycji 2. Oczekiwany element „LightComponentOfDoor7RlNrhPW” z przestrzeni nazw „http://schemas.datacontract.org/2004/07/Test”.. Napotkano „Element” o nazwie „LightComponentOfDoor”, przestrzeń nazw „”.

XML otrzymuję mniej więcej taki:

<LightComponentOfDoor>
  <Session>OperatorSession</Session>
  <ID>424</ID>
  <Description>Controller #1 Door #1 (01.01)</Description>
  <Object>12</Object>
  <Owner>423</Owner>
  <item>
    <key>
      <string>DESCRIPTION2</string>
    </key>
    <value>
      <SmartLinkDataValue>
        <Value>Controller #1 Door #1</Value>
      </SmartLinkDataValue>
    </value>
  </item>
  <item>
    <key>
      <string>ELEVATORCAB</string>
    </key>
    <value>
      <SmartLinkDataValue>
        <Value>0</Value>
      </SmartLinkDataValue>
    </value>
  </item>
</LightComponentOfDoor>

Tak wygląda obiekt:

    [DataContract]
    [KnownType("GetTypes")]
    public class LightComponent<T> : ILightComponent
    {
        [DataMember(Name = "ID")]
        public int Id { get; set; }
        public int Owner { get; set; }
        [DataMember(Name = "Object")]
        public ObjectType Type { get; set; }
        public string Description { get; set; }

        private static Type[] GetTypes()
        {
            return new[] {typeof (LightComponent<T>)};
        }
    }

    [DataContract]
    public class Door
    {
    }

    [DataContract]
    public class Controller
    {
    }

Natomiast kod deserializujący:

            using (var xmlReader = XmlReader.Create(new StringReader(xml)))
            {
                var serializer = new DataContractSerializer(typeof(LightComponent<Door>));
                var obj = serializer.ReadObject(xmlReader);
            }

Zastanawia mnie to "7RlNrhPW" w nazwie oczekiwanego typu. Ktoś się z tym spotkał?

0

Problem jest taki ze serwis nie moze zwracac typow generycznych , co jesli klient ktory bedzie uzywal nie ma w sobie typow generycznych? Hash bierze sie stad ze mozesz miec dwie klasy door w roznych namespace'ach wtedy zwracany contract zawieralby dwie takie same definicje typu (LightComponentOfDoor) dlatego .NET radzi sobie w ten spobos ze dodaje hash do nazwy , nie jest to idealne ale dziala.

0

XML który otrzymuję zapewne pochodzi z WCF, a jednak nie ma hashy i wskazuje na to, że zwraca typ generyczny. Konkretniej root element to ArrayOfLightComponentOfDoor>. Generalnie ja chcę to tylko po ludzku zdeserializować. Najprościej jest dodać klasę LightComponentOfDoor ale tak nie zamierzam robić, chyba że będę musiał.

0

DataContractSerializer ktorego uzywasz , jest uzywany przez WCF do deserializacji wiadomosci , czyli tworzac go dla

typeof(LightComponent<Door>) 

ten serializator tworzy sobie ten hash ( najprawdopodobniej na podstawie nazwy klasy/namespaca) i spodziewa sie ze xml ktory dostaje bedzie zawieral ten element.

0

Rozumiem, tylko co w przypadku gdy dostaję element LightComponentOfDoor?

EDIT:
Rozwiązanie jest takie, że trzeba wymusić nazwę dla elementu przez atrybut:

[DataContract(Name = "LightComponentOf{0}")]

wtedy nie oczekuje już hasha.

Dziękuję za odpowiedzi. Dzięki Tobie znalazłem trop.

1 użytkowników online, w tym zalogowanych: 0, gości: 1