2010-02-11 14 views
6

Ho un array chiamato _updatedComponents di oggetti che sono di classe NetworkComponent. Devo serializzarlo nel modo in cui il nome e lo spazio dei nomi dell'elemento root (= array) vengono modificati e il singolo NetworkComponent-il nome dell'elemento viene modificato in componente. Ho un codice di seguito che causa un'eccezione:come utilizzare XmlAttributeOverrides durante la serializzazione di un array?

System.InvalidOperationException: C'è stato un errore che riflette il tipo 'ComponentSyncService.NetworkComponent []'. ---> System.InvalidOperationException: gli attributi XmlRoot e XmlType potrebbero non essere specificati per il tipo ComponentSyncService.NetworkComponent [].

Codice:

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

Potrei aggiungere che non voglio modificare le definizioni System.Xml.Serialization.XmlTypeAttribute dal momento in cui la classe viene generata e quindi le modifiche andranno perse quando rigenerate –

risposta

8

Che cosa è _updatedComponents? Immagino che sia un NetworkComponent[] - che renderà le cose molto difficili. Suggerirei di scrivere un tipo di wrapper:

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

Quindi è possibile associare gli attributi corretti. Se è necessario supportare gli attributi ad-hoc su NetworkComponent, sarà comunque necessario utilizzare l'attributo-overrides (quindi non ho ancora decorato tutto quanto sopra), ma ComponentsMessage dovrebbe essere felice di prendere gli attributi.

In alternativa, è sufficiente scrivere un DTO separato e mappare i valori.

Se è semplice, si potrebbe anche essere in grado di utilizzare:

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

In alternativa, se si must utilizzare l'attributo-override, sarei ancora utilizza un oggetto 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

grazie per la tua risposta! come dichiaro nella mia domanda: "Ho un array chiamato _updatedComponents di oggetti che sono di classe NetworkComponent." Sto solo lasciando il lavoro, quindi ci provo domani. Peccato che sia complicato. Non ho capito completamente perché ... –

+0

grazie ancora! controllerò la tua risposta modificata prima cosa la mattina. –

+0

ho provato la versione semplice e ha funzionato. molte grazie! Ci metto un sacco di impegno per fornire anche la versione XmlAttributeOverrides. Spero che possa aiutare qualcun altro che ne ha davvero bisogno. –

Problemi correlati