2016-10-24 17 views
0

オブジェクトを直列化して逆シリアル化しようとしています。シリアル化は、[OK]を動作しますが、直列化復元は、シリアル化されたXMLがOKに見えるオブジェクトをシリアル化および逆シリアル化します(XMLドキュメント(0、0)にエラーがあります)。

System.InvalidOperationException : There is an error in XML document (1, 1). 
    ----> System.Xml.XmlException : Data at the root level is invalid. Line 1, position 1. 

スロー:

<?xml version="1.0" encoding="utf-16"?> 
<Data xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="1" Status="OK" xmlns="http://biz.si/Project/v0100/Data.xsd"> 
    <DataGroup Type="SomeType">AAEC</DataGroup> 
</Data> 

エンコーディングがUTF-16、OKですが、私はエンコードの問題が直列化復元中に存在している疑いがあります。コードはテスト環境(ユニットテスト)で実行されていますが、シリアル化されたxmlはWebサービスに送信されます。

これは私のコードです:ここ

[TestFixture] 
public class Foobar 
{ 
    [Test] 
    public void Test() 
    { 
     var d = new Data 
     { 
      Id = "1", 
      Status = "OK", 
      DataGroup = new DataGroup 
      { 
       Type = "SomeType", 
       Value = new byte[] { 0x00, 0x01, 0x02 } 
      } 
     }; 

     var serialized = Serialize(d); 
     var deserialized = Deserialize(serialized); // exception is thrown here. 

     Debug.WriteLine("ok"); 
    } 

    private XmlNode Serialize(Data data) 
    { 
     XmlSerializer xsSubmit = new XmlSerializer(typeof(Data)); 
     StringWriter sww = new StringWriter(); 
     using (XmlWriter writer = XmlWriter.Create(sww)) 
     { 
      xsSubmit.Serialize(writer, data); 
      var xml = sww.ToString(); 
      var xmlDocument = new XmlDocument(); 
      xmlDocument.LoadXml(xml); 
      return xmlDocument; 
     } 
    } 

    private Data Deserialize(XmlNode xmlData) 
    { 
     XmlSerializer xmlSerializer = new XmlSerializer(typeof(Data)); 
     MemoryStream memoryStream = new MemoryStream(Encoding.Default.GetBytes(xmlData.InnerText)); 
     return (Data)xmlSerializer.Deserialize(memoryStream); 
    } 
} 

[XmlRoot(Namespace = "http://biz.si/Project/v0100/Data.xsd", IsNullable = false)] 
[XmlType(AnonymousType = true)] 
public class Data 
{ 
    [XmlAttribute] 
    public string Id { get; set; } 

    [XmlAttribute] 
    public string Status { get; set; } 

    [XmlElement("DataGroup")] 
    public DataGroup DataGroup { get; set; } 
} 

[XmlType(AnonymousType = true)] 
public class DataGroup 
{ 
    [XmlAttribute] 
    public string Type { get; set; } 

    [XmlText(DataType = "base64Binary")] 
    public byte[] Value { get; set; } 
} 

答えて

2

2つの問題:InnerTextがしたいプロパティではありません。それはまったくXMLではありません。デバッガで見てください。次に、MemoryStreamを使用しないでください。あなたがどこにいても、彼はただあなたを運んでいました。 StringReaderは作業がはるかに簡単です。

private Data Deserialize(XmlNode xmlData) 
{ 
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(Data)); 
    using (var stream = new StringReader(xmlData.OuterXml)) 
    { 
     return (Data)xmlSerializer.Deserialize(stream); 
    } 
} 
0

それはそれを好むか、パラメータ少ないコンストラクタなしでクラスをシリアル化することはできません私の経験.NETのXMLシリアル化ですが、次のことができるようにするにはを参照してください。以下は、すべてのXMLシリアル化を行う方法です。私はあなたのクラスを実行し、両方のシリアル化とデシリアライズをうまく動作します。あなたのニーズにそれを微調整することができます。私のテストコードはクラスコードの後ろです。

[XmlRoot(Namespace = "http://biz.si/Project/v0100/Data.xsd", IsNullable = false)] 
    [XmlType(AnonymousType = true)] 
    public class sventevitData 
    { 
    [XmlAttribute] 
    public string Id { get; set; } 

    [XmlAttribute] 
    public string Status { get; set; } 

    [XmlElement("DataGroup")] 
    public DataGroup DataGroup { get; set; } 


    /// <summary> 
    /// Initializes a new instance of the <see cref="sventevitData"/> class. 
    /// Parameterless constructor required for .NET XML serialization 
    /// </summary> 
    public sventevitData(){} 

    public void SerializeData(String FileWithPath) 
    { 
     try 
     { 
     using(Stream stream = new FileStream( FileWithPath,  FileMode.Create, 
               FileAccess.Write, FileShare.Write)) 
     { 
      // Serialize into the storage medium 
      XmlSerializer xmlserial = new XmlSerializer(typeof(sventevitData)); 
      xmlserial.Serialize(stream, this); 
      stream.Close(); 
     } 
     } 
     catch(Exception ex) 
     { 
     string msg = ex.Message; 
     ex = ex.InnerException; 

     while(ex != null) 
     { 
      msg += "" + ex.Message; 
      ex = ex.InnerException; 
     } 

     System.Windows.Forms.MessageBox.Show( 
      String.Format("Exception writing sventevitData {0}: {1}", 
          FileWithPath, msg)); 
     } 
    } 


    public static sventevitData DeserializeData(String FileWithPath) 
    { 
     sventevitData tmp; 
     Stream stream; 

     try 
     { 
     // Read the file back into a stream 
     if(!File.Exists(FileWithPath)) 
     { 
      DirectoryInfo di = null; 

      if(!Directory.Exists(Path.GetDirectoryName(FileWithPath))) 
      { 

      AddDirSecurity(Path.GetDirectoryName(FileWithPath), 
          System.Security.Principal.WindowsIdentity.GetCurrent().Name, 
          FileSystemRights.Write, AccessControlType.Allow); 

      di = Directory.CreateDirectory(Path.GetDirectoryName(FileWithPath)); 
      } 

      AddDirSecurity(FileWithPath, System.Security.Principal.WindowsIdentity.GetCurrent().Name, 
           FileSystemRights.Write, AccessControlType.Allow); 

      File.Create(FileWithPath); 
     } 

     using(stream = new FileStream(FileWithPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     { 
      // Now create a binary formatter 
      XmlSerializer xmlserializer = new XmlSerializer(typeof(sventevitData)); 
      stream = new FileStream(FileWithPath, FileMode.Open, FileAccess.Read, FileShare.Read); 
      tmp = (sventevitData)xmlserializer.Deserialize(stream); 
      stream.Close(); 

      // Deserialize the object and use it 
      return tmp; 
     } 
     } 
     catch(Exception ex) 
     { 
     string msg = ex.Message; 
     ex = ex.InnerException; 

     while(ex != null) 
     { 
      msg += "" + ex.Message; 
      ex = ex.InnerException; 
     } 

     System.Windows.Forms.MessageBox.Show(String.Format("Exception reading {0}: {1}", FileWithPath, msg)); 
     } 

     return new sventevitData(); 
    } 


    private static void AddDirSecurity( String Dir, 
              String Account, 
              FileSystemRights Rights, 
              AccessControlType AccessType) 
    { 
     // Create a new DirectoryInfo object. 
     DirectoryInfo dInfo = new DirectoryInfo(Dir); 

     // Get a DirectorySecurity object that represents the 
     // current security settings. 
     DirectorySecurity dSecurity = dInfo.GetAccessControl(); 

     // Add the FileSystemAccessRule to the security settings. 
     dSecurity.AddAccessRule(new FileSystemAccessRule(Account, Rights, AccessType)); 

     // Set the new access settings. 
     dInfo.SetAccessControl(dSecurity); 
    } 
    } 

    [XmlType(AnonymousType = true)] 
    public class DataGroup 
    { 
    [XmlAttribute] 
    public string Type { get; set; } 

    [XmlText(DataType = "base64Binary")] 
    public byte[] Value { get; set; } 
    } 

[TestClass] 
    public class sventevitDataTest 
    { 
    [TestMethod] 
    [TestCategory("StackOverflow")] 
    public void SerializeTest() 
    { 
     string fileWithPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 
     fileWithPath  = Path.Combine(fileWithPath, "testData.xml"); 

     sventevitData data = new sventevitData(); 

     data.Id   = "1"; 
     data.Status  = "OK"; 
     data.DataGroup = new DataGroup() 
     { 
     Type = "SomeType", 
     Value = new byte[]{ 0x00, 0x01, 0x02 } 
     }; 

     data.SerializeData(fileWithPath); 
    } 


    [TestMethod] 
    [TestCategory("StackOverflow")] 
    public void DeserializeTest() 
    { 
     string fileWithPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 
     fileWithPath  = Path.Combine(fileWithPath, "testData.xml"); 

     sventevitData data = sventevitData.DeserializeData(fileWithPath); 
    } 
    } 

はXMLを含むことを忘れない定義コンストラクタと

<?xml version="1.0"?> 
<sventevitData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Id="1" Status="OK" xmlns="http://biz.si/Project/v0100/Data.xsd"> 
    <DataGroup Type="SomeType">AAEC</DataGroup> 
</sventevitData> 
+1

A C#クラスは、パラメータなし(ベースクラスはない公共のパラメータなしのコンストラクタを有していない面白いケースを付与する)デフォルトのコンストラクタを有します。これが、パラメータのないコンストラクタを持たないように見えるクラスを直列化することができるように見える理由です。彼の 'Test()'メソッドは、コンストラクタパラメータなしで 'Data' *のインスタンスを生成することに注意してください。*:' var d = new Data {}; '。それは無パラメータのコンストラクタです。 –

+1

情報ありがとうございました!私は新しいことを学ぶのが大好きです。 – DB9

関連する問題