2012-10-12 15 views
5

w montażu A:deserializacji typu uzyskano przy użyciu DataContractSerializer gdy typ pochodne nie są znane wcześniej

[DataContract]  
     public class Base 
     { 
      [DataMember] 
      public string SomeText { get; set; } 
     } 

w montażu B:

internal class Helper 
     { 
      internal static Base Deserialize(string serializedInstanceOfTypeBase) 
    { 
        DataContractSerializer serializer = new DataContractSerializer(typeof (Base)); 
        XmlReader reader = XmlReader.Create(new StringReader(serializedInstanceOfTypeBase)); 
        return (Base)serializer.ReadObject(reader); 
    } 
    } 

w montażu C:

[DataContract]  
     public class Derived : Base 
     { 
      [DataMember] 
      public string SomeMoreText { get; set; } 
     } 

Gdybym serializacji instancji typu Derived i przekazać go do Helper.Deserialize() metody, nie jest on z SerializationException:

Błąd w wierszu 1 pozycji 2. Spodziewa element „Baza” z nazw „http: // schematy .datacontract.org/2004/07 '.. Napotkano' Element ' o nazwie "Pochodny", przestrzeń nazw "http://schemas.datacontract.org/2004/07".

Jak mogę pozbyć się tego problemu?

Znam atrybut KnownType, ale w czasie kodowania w złożeniu A i B, absolutnie nie jestem świadomy jego typów pochodnych. Więc nie mogę użyć tego rozwiązania.

Projekt mojego produktu jest bardziej skomplikowany i nie mogę go tutaj opublikować. Metoda Helper.Desrialize() po prostu pobiera argument string. Nie ma sposobu (przynajmniej obecnie) na zespół A lub B, aby wiedzieć o pochodnych typach klasy Base, nawet w czasie wykonywania.

Assembly B montaż odniesienia A. Ale & B nie mogą odwoływać się do montażu C.

Używam C# 4.0. Jest OK, jeśli podane przez ciebie rozwiązanie NIE JEST używane DataContractSerializer.

+1

Nie wiem o gotowym rozwiązaniu. Wiem z własnego doświadczenia, gdy miałem wiele różnych typów, w istocie podwójnie serializuje moje treści z informacjami o typie. To znaczy, chciałbym mieć "SerializedObject", który zawierałby pełne informacje o typie (nazwa zespołu, pełna nazwa klasy) wraz z serializowanym łańcuchem XML.Moja warstwa przesyłania danych silnie wpisywałaby się w 'SerializedObject', pobierała referencje do typu (np. Poprzez' Type.GetType'), a następnie odpowiednio przekształcała dane XML za pomocą XmlSerializer. –

+0

Masz na myśli, że klasa "Baza" jest w klasie "A" a klasa "Pochodząca" w "Zgromadzeniu C"? Jeśli tak jest, to myślę, że to jest problem. Kontrakty danych powinny być zdefiniowane w tym samym zespole. Kontrakty DataContracts nie powinny być dzielone na zespoły. – jags

Odpowiedz

2

Czy znasz typy w czasie wykonywania? Jeśli tak, to proste podejście może być tylko:

List<Type> knownTypes = ...; // now that you know what to expect 
DataContractSerializer serializer = new DataContractSerializer(
    typeof(Base), knownTypes); 
+0

Dzięki za odpowiedź. Jest to bardzo pomocne, ale dodałem więcej szczegółów do pytania. Powinienem był wcześniej dodać te szczegóły. Zauważ, że klasa 'Helper' jest w innym zestawie i nie jest' public '. Ponadto, metoda "Deserialize" po prostu pobiera dowolną wartość ciągu. – Learner

Powiązane problemy