序列化和反序列化对象(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看起来没问题:

<?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,这是可以的,但我怀疑在反序列化过程中存在编码问题。现在代码在测试环境(单元测试)中运行,但是序列化的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://www.demo.com", 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; }
}

这里有两个问题: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);
    }
}

根据我的经验,. 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>

最新更新