c#中的XML反序列化返回一个空对象

本文关键字:一个 对象 中的 XML 反序列化 返回 | 更新日期: 2023-09-27 18:17:42

我有一个关于反序列化的问题。我有一个XML文件,需要将其反序列化为从Service引用获得的类。我知道如何反序列化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>,因为当反序列化时,它会抛出和异常是不期望的。

最后几句话,我不能更改服务引用类,我需要稍后使用这个类,所以我不能自己创建

c#中的XML反序列化返回一个空对象

区别在于名称空间-根据FileDescription类上的XmlType属性,名称空间是http://www.v.lt/c/i/iv。这适用于FileDescription的所有子元素。根名称空间是您通过XmlRootAttribute或接受默认名称空间的构造函数配置的任何名称空间。

正如我所建议的,调试这类问题最简单的方法是反向操作——序列化对象,看看它是什么样子。正如您在这段代码中看到的,当前的输出看起来是这样的。这就是为什么您没有得到任何错误(因为根类匹配),但是您反序列化的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>

如果您为根指定了与本文中相同的名称空间,则输出如下所示:

<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>

您需要在修改后的文档中保留名称空间。

(代表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>

现在可以正常工作了,谢谢你的帮助。