2010-02-11 14 views
6

Mam tablicę o nazwie _updatedComponents obiektów, które są klasy NetworkComponent. Muszę serializować go w taki sposób, że zmieni się nazwa i przestrzeń nazw elementu głównego (= tablica) i nazwa pojedynczego elementu NetworkComponent zostanie zmieniona na składnik. Mam kod poniżej, który powoduje wyjątek:jak korzystać z XmlAttributeOverrides podczas serializacji tablicy?

System.InvalidOperationException: Wystąpił błąd odzwierciedlający typ "ComponentSyncService.NetworkComponent []". ---> System.InvalidOperationException: Atrybuty XmlRoot i XmlType nie mogą być określone dla typu ComponentSyncService.NetworkComponent [].

Kod:

XmlAttributeOverrides xaos = new XmlAttributeOverrides(); 

// the array itself aka the root. change name and namespace 
XmlElementAttribute xea = new XmlElementAttribute(_updatedComponents.GetType()); 
xea.Namespace = "http://www.example.com/nis/componentsync"; 
xea.ElementName = "components"; 

XmlAttributes xas = new XmlAttributes(); 
xas.XmlElements.Add(xea); 
xaos.Add(_updatedComponents.GetType(), xas); 

// then the items of the array. just change the name 
xea = new XmlElementAttribute(typeof(networkcomponent)); 
xea.ElementName = "component"; 

xas = new XmlAttributes(); 
xas.XmlElements.Add(xea); 
xaos.Add(typeof(NetworkComponent), "NetworkComponent", xas); 

XmlSerializer serializer = new XmlSerializer(_updatedComponents.GetType(), xaos); 

XmlTextWriter writer = new XmlTextWriter(string.Format("{0}\\ComponentSyncWS_{1}.xml", 
         Preferences.FileSyncDirectory, requestId), Encoding.UTF8); 
serializer.Serialize(writer, _updatedComponents); 
+0

Mogę dodać, że nie chcę zmieniać definicji System.Xml.Serialization.XmlTypeAttribute, ponieważ klasa jest generowana, a zatem zmiany zostaną utracone po zregenerowaniu –

Odpowiedz

8

Co jest _updatedComponents? Zgaduję, że to jest NetworkComponent[] - co sprawi, że sprawy będą bardzo trudne. Sugerowałbym napisanie typu opakowania:

public class ComponentsMessage { 
    public NetworkComponent[] Components {get;set;} 
} 

Następnie można skojarzyć prawidłowe atrybuty. Jeśli potrzebujesz obsługi atrybutów ad-hoc na NetworkComponent, nadal będziesz musiał używać nadpisań atrybutów (stąd nie dekorowałem tego w ogóle), ale ComponentsMessage powinien być szczęśliwy, aby wziąć atrybuty.

Alternatywnie, po prostu napisz osobny DTO i zmapuj wartości.

Jeśli to jest proste, może po prostu być w stanie używać:

[XmlRoot("components", Namespace = XmlNamespace)] 
[XmlType("components", Namespace = XmlNamespace)] 
public class ComponentsMessage 
{ 
    public const string XmlNamespace = "http://www.example.com/nis/componentsync"; 
    [XmlElement("component")] 
    public NetworkComponent[] Components { get; set; } 
} 

Ewentualnie, jeśli must użytku atrybut nadpisania, będę nadal używać obiektu Wrapper:

public class ComponentsMessage 
{ 
    public NetworkComponent[] Components { get; set; } 
} 
class Program 
{ 
    static void Main() 
    { 
     NetworkComponent[] _updatedComponents = new NetworkComponent[2] { 
      new NetworkComponent{},new NetworkComponent{} 
     }; 
     const string XmlNamespace = "http://www.example.com/nis/componentsync"; 
     XmlAttributeOverrides ao = new XmlAttributeOverrides(); 
     ao.Add(typeof(ComponentsMessage), new XmlAttributes { 
      XmlRoot = new XmlRootAttribute("components") { Namespace = XmlNamespace }, 
      XmlType = new XmlTypeAttribute("components") { Namespace = XmlNamespace } 
     }); 
     ao.Add(typeof(ComponentsMessage), "Components", new XmlAttributes { 
      XmlElements = { 
       new XmlElementAttribute("component") 
      } 
     }); 
     ComponentsMessage msg = new ComponentsMessage { Components = _updatedComponents }; 
     XmlSerializer serializer = new XmlSerializer(msg.GetType(), ao); 
     serializer.Serialize(Console.Out, msg); 
    } 
} 
+0

dzięki za odpowiedź! jak stwierdzam w moim pytaniu: "Mam tablicę o nazwie _updatedComponents obiektów, które są klasy NetworkComponent." Właśnie wychodzę z pracy, więc spróbuję jutro. Szkoda, że ​​to trudne. Nie w pełni rozumiem, dlaczego ... –

+0

dzięki jeszcze raz! Sprawdzę twoją zredagowaną odpowiedź Pierwszą rzeczą rano. –

+0

Próbowałem prostej wersji i działało. wielkie dzięki! włożyliśmy wiele wysiłku, aby zapewnić także wersję XmlAttributeOverrides. Mam nadzieję, że pomoże komuś, kto naprawdę tego potrzebuje. –

Powiązane problemy