XML C# 中的反序列化 returns 空对象
XML deserialization in C# returns an empty object
我有一个关于反序列化的问题。我有一个 XML 文件,我需要将其反序列化为从服务引用中获取的 class。我知道如何反序列化一个 XML 文件,但是当我尝试反序列化这个文件时,我得到一个空的 class 对象。我不明白为什么要这样做。
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"</SoftwareCompanyName>
<SoftwareName>Eita</SoftwareName>
<SoftwareVersion>2016.9</SoftwareVersion>
<CreatorRegistrationNumber>123060356</CreatorRegistrationNumber>
</FileDescription>
</iVAZFile>
class 看起来像这样:
[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));
}
}
}
以及我用来填充 class 的方法:
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);
}
}
}
}
一些额外的评论来说明我也试过了:
- 我制作了自己的 class,看起来与服务参考中的相同,并添加了一个新参数
[XmlRoot(ElementName="FileDescription"),XmlType("FileDescription")]
然后反序列化对我的 class. 起作用
- 尝试在没有反序列化的情况下手动添加值,效果也很好,因此服务代码没有问题。
- 此外,当我反序列化 xml 时,我删除了
<iVAZFile xmlns="http://www.v.lt/c/i/iv">
和 </iVAZFIle>
,因为反序列化时它会抛出异常,而 .
最后说几句,我无法更改服务参考 class,我以后需要使用那个 class,所以我不能自己制作。
不同之处在于命名空间 - 根据 FileDescription
class 上的 XmlType
属性,命名空间是 http://www.v.lt/c/i/iv
。这适用于 FileDescription
的所有子元素。根命名空间是您通过 XmlRootAttribute
或采用默认命名空间的构造函数配置的任何内容。
正如我所建议的,调试此类问题的最简单方法是执行相反的操作 - 序列化 一个对象并查看它的外观。正如您在 this fiddle 中所见,目前的输出看起来像这样。这就是为什么你没有收到任何错误(因为根 class 匹配),但是你正在反序列化的 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.
中看到这个作品
(代表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"</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>
现在可以正常使用了,感谢帮助。
我有一个关于反序列化的问题。我有一个 XML 文件,我需要将其反序列化为从服务引用中获取的 class。我知道如何反序列化一个 XML 文件,但是当我尝试反序列化这个文件时,我得到一个空的 class 对象。我不明白为什么要这样做。
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"</SoftwareCompanyName>
<SoftwareName>Eita</SoftwareName>
<SoftwareVersion>2016.9</SoftwareVersion>
<CreatorRegistrationNumber>123060356</CreatorRegistrationNumber>
</FileDescription>
</iVAZFile>
class 看起来像这样:
[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));
}
}
}
以及我用来填充 class 的方法:
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);
}
}
}
}
一些额外的评论来说明我也试过了:
- 我制作了自己的 class,看起来与服务参考中的相同,并添加了一个新参数
[XmlRoot(ElementName="FileDescription"),XmlType("FileDescription")]
然后反序列化对我的 class. 起作用
- 尝试在没有反序列化的情况下手动添加值,效果也很好,因此服务代码没有问题。
- 此外,当我反序列化 xml 时,我删除了
<iVAZFile xmlns="http://www.v.lt/c/i/iv">
和</iVAZFIle>
,因为反序列化时它会抛出异常,而 .
最后说几句,我无法更改服务参考 class,我以后需要使用那个 class,所以我不能自己制作。
不同之处在于命名空间 - 根据 FileDescription
class 上的 XmlType
属性,命名空间是 http://www.v.lt/c/i/iv
。这适用于 FileDescription
的所有子元素。根命名空间是您通过 XmlRootAttribute
或采用默认命名空间的构造函数配置的任何内容。
正如我所建议的,调试此类问题的最简单方法是执行相反的操作 - 序列化 一个对象并查看它的外观。正如您在 this fiddle 中所见,目前的输出看起来像这样。这就是为什么你没有收到任何错误(因为根 class 匹配),但是你正在反序列化的 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.
中看到这个作品(代表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"</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>
现在可以正常使用了,感谢帮助。