DataContractSerializer pas désérialisation toutes les variables
-
28-09-2019 - |
Question
Je suis en train de désérialiser certains xml sans avoir la classe d'origine qui a été utilisé pour créer l'objet en XML. La classe est appelée ComOpcClientConfiguration.
Il est la mise en valeur avec succès les ServerUrl et ServerUrlHda, mais pas de repos d'entre eux ...
Donc ce que je demande est: Comment puis-je faire le reste de ces valeurs se correctement réglée, et pourquoi sont-ils pas travailler avec mon code actuel
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 les types connus pirater je. Mais pour l'instant c'est ce que j'ai.
Voici le xml qu'il regarde 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 sérialiseur parce que je ne sais pas exactement comment l'ensemble des travaux stuff nommant le type.
[DataContract(Name = "ComOpcClientConfiguration", Namespace = "http://opcfoundation.org/UA/SDK/COMInterop")]
public class ComOpcClientConfiguration
{
public ComOpcClientConfiguration() { }
... Same innards as ComClientConfiguration
}
La solution
Données-contrat-sérialiseur est ... Fussy. En particulier, je me demande si tout simplement l'ordre des éléments est le problème ici. Cependant, il est pas nécessairement le meilleur outil pour travailler avec XML. XmlSerializer est probablement ici plus robuste - il peut gérer une gamme beaucoup mieux de XML. DCS est tout simplement pas destiné à ce que de primaire but.
Avec XML simple, vous souvent même pas besoin d'attributs, etc. Vous pouvez même utiliser xsd.exe sur votre XML existant pour générer la mise en correspondance c classes # (en deux étapes, XML à xsd; xsd à c # ).
Autres conseils
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)]
..