DataContractSerializerは、すべての変数を降下させません
-
28-09-2019 - |
質問
XMLでオブジェクトを作成するために使用された元のクラスを持たずに、いくつかのXMLを脱上しようとしています。クラスはcomopcclientconfigurationと呼ばれます。
ServerUrlとServerlhdaの値を成功して設定していますが、残りはありません...
だから私が尋ねているのは、これらの値の残りを適切に設定するにはどうすればよいか、そしてなぜ彼らが私の現在のコードを使用していないのかということです。
これが私の脱審設計コードです:
confは、ComClientConfiguration XMLを表すXelementです
DataContractSerializer ser = new DataContractSerializer(typeof(ComClientConfiguration), new Type[] {typeof(ComClientConfiguration), typeof(ComOpcClientConfiguration) });
ComOpcClientConfiguration config = (ComOpcClientConfiguration)ser.ReadObject(conf.CreateReader());
ComClientConfigurationとcomopcclientConfigurationを必要としなければならない理由はわかりませんが、おそらく私が持っている既知のタイプのハックを行うより良い方法があります。しかし、今のところそれは私が持っているものです。
これがファイルで見られるXMLです。
<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>
これが私が次のように降下するために構築したクラスです:
[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
}
さらに、このクラスを作らなければなりませんでしたが、同じですが、名前は異なります。シリアルの既知のタイプに使用されます。なぜなら、タイプのネーミングスタッフ全体がどのように機能するかを正確に知らないからです。
[DataContract(Name = "ComOpcClientConfiguration", Namespace = "http://opcfoundation.org/UA/SDK/COMInterop")]
public class ComOpcClientConfiguration
{
public ComOpcClientConfiguration() { }
... Same innards as ComClientConfiguration
}
解決
データコントラクトシリアルは...うるさいです。特に、ここでは単に要素の順序が問題であるのだろうかと思います。ただし、必ずしもXMLを操作するための最良のツールではありません。 XMLSerializerはおそらくここではより堅牢です - XMLのはるかに優れた範囲を処理できます。 DCSは単にそれを意図していません 主要な ゴール。
単純なXMLを使用すると、属性なども必要ありません。既存のXMLでXSD.EXEを使用して、一致するC#クラス(2つのステップで; XML-to-XSD; XSD-to-C#)を生成することもできます。
他のヒント
すべての値を取得するには、注文のハードコードを試してみてください(それ以外の場合は、アルファベット順の順序を試します):
[DataMember(Name = "ServerUrl", Order = 0)]
..
[DataMember(Name = "ServerName", Order = 1)]
..
[DataMember(Name = "ServerNamespaceUrl", Order = 2)]
..
[DataMember(Name = "MaxReconnectWait", Order = 3)]
..