2010-10-08 10 views
4

J'essaie de désérialiser certains fichiers XML sans avoir la classe d'origine utilisée pour créer l'objet dans xml. La classe s'appelle ComOpcClientConfiguration.
Il définit avec succès les valeurs ServerUrl et ServerUrlHda, mais pas le reste ...
Donc, ce que je demande est: Comment puis-je faire le reste de ces valeurs se régler correctement, et pourquoi ne fonctionnent-ils pas avec mon code actuel.DataContractSerializer ne désérialise pas toutes les variables

Voici mon code désérialisation:
conf est un XElement qui représente la ComClientConfiguration xml

DataContractSerializer ser = new DataContractSerializer(typeof(ComClientConfiguration), new Type[] {typeof(ComClientConfiguration), typeof(ComOpcClientConfiguration) }); 
ComOpcClientConfiguration config = (ComOpcClientConfiguration)ser.ReadObject(conf.CreateReader()); 

Je ne sais pas pourquoi je dois avoir ComClientConfiguration et ComOpcClientConfiguration, il y a probablement une meilleure façon de faire la types connus pirater j'ai. Mais pour l'instant c'est ce que j'ai.

Voici le fichier XML tel qu'il apparaît dans le fichier.

<ComClientConfiguration xsi:type="ComOpcClientConfiguration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <ServerUrl>The url</ServerUrl> 
    <ServerName>a server name </ServerName> 
    <ServerNamespaceUrl>a namespace url</ServerNamespaceUrl> 
    <MaxReconnectWait>5000</MaxReconnectWait> 
    <MaxReconnectAttempts>0</MaxReconnectAttempts> 
    <FastBrowsing>true</FastBrowsing> 
    <ItemIdEqualToName>true</ItemIdEqualToName> 
    <ServerUrlHda>hda url</ServerUrlHda> 
</ComClientConfiguration> 

Voici la classe I construit désérialiser dans:

[DataContract(Name = "ComClientConfiguration", Namespace = "http://opcfoundation.org/UA/SDK/COMInterop")] 
public class ComClientConfiguration 
{ 
    public ComClientConfiguration() { } 

    //Prog-ID for DA-connection 
    [DataMember(Name = "ServerUrl"), OptionalField] 
    public string ServerUrl;//url 
    [DataMember(Name = "ServerName")] 
    public string ServerName; 
    [DataMember(Name = "ServerNamespaceUrl")] 
    public string ServerNamespaceUrl;//url 
    [DataMember(Name = "MaxReconnectWait")] 
    public int MaxReconnectWait; 
    [DataMember(Name = "MaxReconnectAttempts")] 
    public int MaxReconnectAttempts; 
    [DataMember(Name = "FastBrowsing")] 
    public bool FastBrowsing; 
    [DataMember(Name = "ItemIdEqualToName")] 
    public bool ItemIdEqualToName; 

    //ProgID for DA-connection 
    [DataMember, OptionalField] 
    public string ServerUrlHda;//url 
} 

J'ai eu en plus de faire de cette classe, il est le même, mais avec un nom différent. Utilisé pour les types connus dans le Serializer parce que je ne sais pas exactement comment fonctionne le tout.

[DataContract(Name = "ComOpcClientConfiguration", Namespace = "http://opcfoundation.org/UA/SDK/COMInterop")] 
public class ComOpcClientConfiguration 
{ 
    public ComOpcClientConfiguration() { } 

    ... Same innards as ComClientConfiguration 
} 

Répondre

3

Data-contrat-serializer est ... Fussy. En particulier, je me demande si simplement l'ordre des éléments est le problème ici. Cependant, ce n'est pas nécessairement le meilleur outil pour travailler avec XML. XmlSerializer est probablement plus robuste ici - il peut gérer une bien meilleure gamme de XML. DCS n'est tout simplement pas prévu avec cela, car c'est l'objectif principal . Avec un XML simple, vous n'avez souvent besoin d'aucun attribut, etc. Vous pouvez même utiliser xsd.exe sur votre XML existant pour générer les classes C# correspondantes (en deux étapes: XML-to-xsd; xsd-to- C#).

2

Pour obtenir toutes les valeurs, essayez hardcoding l'ordre (sinon peut-être l'ordre alphabétique tente):

[DataMember(Name = "ServerUrl", Order = 0)] 
.. 
[DataMember(Name = "ServerName", Order = 1)] 
.. 
[DataMember(Name = "ServerNamespaceUrl", Order = 2)] 
.. 
[DataMember(Name = "MaxReconnectWait", Order = 3)] 
.. 
Questions connexes