2016-11-14 5 views
0

デシリアライズについてはここで問題があります。私は、私がサービス参照から得たクラスに非直列化する必要があるXMLファイルを持っています。私はXMLファイルを逆シリアル化する方法を知っていますが、このファイルを逆シリアル化しようとすると空のクラスオブジェクトが生成されます。なぜ私はそれをやっているのか分かりません。C#でXMLの直列化を解除すると、空のオブジェクトが返されます

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

これを逆に実行して、オブジェクトを作成してシリアル化します。あなたは違いがどこにあるのかを簡単に見つけ出すでしょう。あなたが 'FileDescription'を期待する何かを使って' iVAZFile'要素をデシリアライズしようとしていることは、私にはたくさんあります。 –

+0

ええ、私はを削除することを忘れてしまいました。デシリアライズすると例外がスローされ、 "

+0

名前空間( 'xmlns'属性)を' FileDescription'に追加しますか?そうでない場合、一致しません。 –

答えて

1

違いは、FileDescriptionクラスのXmlType属性ごとに、ネームスペースはhttp://www.v.lt/c/i/ivです。これは、FileDescriptionのすべての子要素に適用されます。ルート名前空間は、XmlRootAttributeまたはデフォルトの名前空間を使用するコンストラクタを使用して設定するものです。

私が提案したように、この種の問題をデバッグする最も簡単な方法は、逆の処理を行うことです。serialiseオブジェクトを見て、どのように見えるかを確認します。 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

(OPの代わりに掲示)

問題はCharles Magerのおかげで解決されました。問題は、私はそれがこのように見えなければならないので、私の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> 

今では正常に動作し、助けに感謝を。

関連する問題