DataContractSerializer не десериализует все переменные - PullRequest
4 голосов
/ 08 октября 2010

Я пытаюсь десериализовать некоторые xml без исходного класса, который использовался для создания объекта в xml. Класс называется ComOpcClientConfiguration.
Он успешно устанавливает значения ServerUrl и ServerUrlHda, но не остальные из них ...
Итак, я спрашиваю: как я могу сделать так, чтобы остальные значения были правильно установлены, и почему они не работают с моим текущим кодом?

Вот мой код десериализации:
conf - это XElement, который представляет ComClientConfiguration xml

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
}

Ответы [ 2 ]

3 голосов
/ 09 октября 2010

Данные-контракт-сериализатор это ... суетливый.В частности, мне интересно, если проблема заключается в простом порядке элементов.Однако это также не обязательно лучший инструмент для работы с XML.XmlSerializer здесь, вероятно, более надежный - он может обрабатывать гораздо лучший диапазон XML.DCS просто не предназначен для этого, поскольку это основная цель.

С простым XML вам часто даже не нужны никакие атрибуты и т. Д. Вы даже можете использовать xsd.exe в существующем XMLсоздать соответствующие классы c # (в два этапа; XML-to-xsd; xsd-to-c #).

2 голосов
/ 18 апреля 2014

Чтобы получить все значения, попробуйте жестко прописать порядок (в противном случае, возможно, он пробует алфавитный порядок):

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