繁体   English   中英

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

[英]XML deserialization in C# returns an empty object

我在这里有关于反序列化的问题。 我有一个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>因为反序列化时会抛出异常,并且不会发生异常。

最后,我无法更改服务引用类,并且以后需要使用该类,因此无法创建自己的类。

区别在于名称空间-根据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>

现在工作正常,谢谢您的帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM