2016-11-14 4 views
0

У меня проблема с десериализацией. У меня есть XML-файл, который мне нужно десериализовать в класс, который я получаю из справки Service. Я знаю, как десериализовать XML-файл, но когда я пытаюсь десериализовать этот файл, я получаю пустой объект класса. Я не понимаю, почему это так.XML-десериализация в C# возвращает пустой объект

Содержание XML файлы выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8" ?><iVAZFile xmlns="http://www.v.lt/c/i/iv"> 
<FileDescription> 
<FileVersion>i1.3.3</FileVersion> 
<FileDateCreated>2016-11-07T12:28:32</FileDateCreated> 
<SoftwareCompanyName>otechnika&quot;</SoftwareCompanyName> 
<SoftwareName>Eita</SoftwareName> 
<SoftwareVersion>2016.9</SoftwareVersion> 
<CreatorRegistrationNumber>123060356</CreatorRegistrationNumber> 
</FileDescription> 
</iVAZFile> 

Класс выглядит следующим образом:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.1590.0")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.v.lt/c/i/iv")] 
    public partial class FileDescription : object, System.ComponentModel.INotifyPropertyChanged { 

     private string fileVersionField; 

     private System.DateTime fileDateCreatedField; 

     private string softwareCompanyNameField; 

     private string softwareNameField; 

     private string softwareVersionField; 

     private ulong creatorRegistrationNumberField; 

     public FileDescription() { 
      this.fileVersionField = "iVAZ1.3.3"; 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Order=0)] 
     public string FileVersion { 
      get { 
       return this.fileVersionField; 
      } 
      set { 
       this.fileVersionField = value; 
       this.RaisePropertyChanged("FileVersion"); 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Order=1)] 
     public System.DateTime FileDateCreated { 
      get { 
       return this.fileDateCreatedField; 
      } 
      set { 
       this.fileDateCreatedField = value; 
       this.RaisePropertyChanged("FileDateCreated"); 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Order=2)] 
     public string SoftwareCompanyName { 
      get { 
       return this.softwareCompanyNameField; 
      } 
      set { 
       this.softwareCompanyNameField = value; 
       this.RaisePropertyChanged("SoftwareCompanyName"); 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Order=3)] 
     public string SoftwareName { 
      get { 
       return this.softwareNameField; 
      } 
      set { 
       this.softwareNameField = value; 
       this.RaisePropertyChanged("SoftwareName"); 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Order=4)] 
     public string SoftwareVersion { 
      get { 
       return this.softwareVersionField; 
      } 
      set { 
       this.softwareVersionField = value; 
       this.RaisePropertyChanged("SoftwareVersion"); 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute(Order=5)] 
     public ulong CreatorRegistrationNumber { 
      get { 
       return this.creatorRegistrationNumberField; 
      } 
      set { 
       this.creatorRegistrationNumberField = value; 
       this.RaisePropertyChanged("CreatorRegistrationNumber"); 
      } 
     } 

     public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 

     protected void RaisePropertyChanged(string propertyName) { 
      System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; 
      if ((propertyChanged != null)) { 
       propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 

И метод, который я использую для заполнения класса:

using (MemoryStream memoryStream = new MemoryStream()) 
      { 
       using (BinaryWriter binWriter = new BinaryWriter(memoryStream, Encoding.UTF8)) 
       { 
        string filep = File.ReadAllText("test.xml"); 
        binWriter.Write(filep); 
        memoryStream.Seek(2, SeekOrigin.Begin); 
        using (StreamReader streamReader = new StreamReader(memoryStream)) 
        { 
         using (XmlReader reader = XmlReader.Create(streamReader)) 
         { 
          XmlRootAttribute xRoot = new XmlRootAttribute(); 
          xRoot.ElementName = "FileDescription"; 
          xRoot.IsNullable = false; 
          XmlSerializer serializer = new XmlSerializer(typeof(FileDescription),xRoot); 
          FileDescription dsc = new FileDescription(); 
          dsc=(FileDescription)serializer.Deserialize(reader); 
         } 
        } 
       } 
       } 

Несколько дополнительных комментариев, чтобы сказать, что я также пробовал:

  1. Я сделал свой собственный класс, который выглядел так же, как тот, который был использован в сервисной ссылке, и добавил новый параметр [XmlRoot(ElementName="FileDescription"),XmlType("FileDescription")] , после чего работа по десерилизации работала над моим классом.
  2. Пробовал добавлять значения вручную без десерилизации, которые отлично работали, поэтому нет проблем с кодом обслуживания.
  3. Также, когда я десериализую xml, я удаляю <iVAZFile xmlns="http://www.v.lt/c/i/iv"> и </iVAZFIle>, потому что при десериализации он будет метаться и исключение не ожидалось.

И, наконец, несколько слов, я не могу изменить класс ссылок службы, и мне нужно использовать этот класс для последующего использования, поэтому я не могу сделать свой собственный.

+1

Сделайте это в обратном порядке - создайте объект и сериализуйте его. Вы будете легче определить, где различия. Мне очень много кажется, что вы пытаетесь десериализовать элемент 'iVAZFile', используя что-то, что ожидает' FileDescription'. –

+0

Да, я забыл добавить, что я также удаляю и, потому что при десериализации он будет бросать и исключать "не ожидал

+0

Вы добавляете пространство имен (атрибут 'xmlns') обратно в' FileDescription'? Если нет, они не совпадут. –

ответ

1

Разница - это пространство имен - по атрибуту XmlType на вашем классе FileDescription, пространство имен - http://www.v.lt/c/i/iv. Это относится ко всем дочерним элементам FileDescription. Корневое пространство имен - это то, что вы настраиваете через свой XmlRootAttribute, или конструктором, который занимает пространство имен по умолчанию.

Как я и предположил, самый простой способ отладить этот вопрос - сделать обратный - сериализуйте объект и посмотрите, как он выглядит. Как вы можете видеть в this fiddle, результат в настоящее время будет выглядеть следующим образом. Вот почему вы не получаете никаких ошибок (по мере совпадения корневого класса), но все дочерние элементы в десериализаторе XML находятся в неправильном пространстве имен.

<FileDescription> 
    <FileVersion xmlns="http://www.v.lt/c/i/iv">iVAZ1.3.3</FileVersion> 
    <FileDateCreated xmlns="http://www.v.lt/c/i/iv">0001-01-01T00:00:00</FileDateCreated> 
    <CreatorRegistrationNumber xmlns="http://www.v.lt/c/i/iv">0</CreatorRegistrationNumber> 
</FileDescription> 

Если указать то же пространство имен для корня, как и в this fiddle, результат выглядит следующим образом:

<FileDescription xmlns="http://www.v.lt/c/i/iv"> 
    <FileVersion>iVAZ1.3.3</FileVersion> 
    <FileDateCreated>0001-01-01T00:00:00</FileDateCreated> 
    <CreatorRegistrationNumber>0</CreatorRegistrationNumber> 
</FileDescription> 

Вы должны сохранить пространство имен в вашем измененном документе. Вы можете видеть, как это работает в this fiddle.

+0

Спасибо, что решил мою проблему –

0

(Отправлено от имени ОП).

Проблема решена благодаря Чарльзу Мэгеру. Проблема заключалась в том, я должен был добавить пространство имен для каждого значения в моем XML, так что бы выглядеть следующим образом:

<FileDescription> 
<FileVersion xmlns="http://www.v.lt/c/i/iv">i1.3.3</FileVersion> 
<FileDateCreated xmlns="http://www.v.lt/c/i/iv">2016-11-07T12:28:32</FileDateCreated> 
<SoftwareCompanyName xmlns="http://www.v.lt/c/i/iv">otechnika&quot;</SoftwareCompanyName> 
<SoftwareName xmlns="http://www.v.lt/c/i/iv">Eita</SoftwareName> 
<SoftwareVersion xmlns="http://www.v.lt/c/i/iv">2016.9</SoftwareVersion> 
<CreatorRegistrationNumber xmlns="http://www.v.lt/c/i/iv">123060356</CreatorRegistrationNumber> 
</FileDescription> 

Сейчас он работает отлично, спасибо за помощь.

Смежные вопросы