2010-02-11 4 views
6

J'ai un tableau appelé _updatedComponents d'objets de la classe NetworkComponent. Je dois le sérialiser de la façon dont le nom et l'espace de noms de l'élément racine (= tableau) est changé et le nom de l'élément NetworkComponent individuel est changé en composant. J'ai un code ci-dessous qui provoque une exception:comment utiliser XmlAttributeOverrides lors de la sérialisation d'un tableau?

System.InvalidOperationException: Il y avait un type réfléchissant d'erreur 'ComponentSyncService.NetworkComponent []. ---> System.InvalidOperationException: Les attributs XmlRoot et XmlType ne peuvent pas être spécifiés pour le type ComponentSyncService.NetworkComponent [].

code:

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

je pourrais ajouter que je ne veux pas changer les définitions de System.Xml.Serialization.XmlTypeAttribute puisque la classe est générée et ainsi les changements seront perdus une fois régénérés –

Répondre

8

Qu'est-ce que _updatedComponents? Je suppose que c'est un NetworkComponent[] - ce qui rendra les choses très difficiles. Je suggère d'écrire un type de wrapper:

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

Ensuite, vous pouvez associer les attributs corrects. Si vous avez besoin de prendre en charge les attributs ad-hoc sur NetworkComponent, vous devrez toujours utiliser les attributs-overrides (donc je n'ai pas du tout décoré le tout), mais ComponentsMessage devrait être heureux de prendre les attributs.

Alternativement, écrivez simplement un DTO séparé et mappez les valeurs.

Si elle est simple, vous pourriez être en mesure d'utiliser:

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

Alternativement, si vous must utilisation attribut-overrides, je toujours utiliser un objet emballage:

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

merci pour votre réponse! comme je le dis dans ma question: "J'ai un tableau appelé _updatedComponents d'objets qui sont de classe NetworkComponent." Je laisse juste le travail alors je l'essaie demain. Dommage que ce soit difficile. Je n'ai pas entièrement compris pourquoi ... –

+0

merci encore! Je vais vérifier votre réponse éditée la première chose le matin. –

+0

J'ai essayé la version simple et cela a fonctionné. Merci beaucoup! Vous avez mis beaucoup d'efforts pour fournir aussi la version XmlAttributeOverrides. J'espère que cela aidera quelqu'un d'autre qui en a vraiment besoin. –

Questions connexes