我的问题可能源于对 XML 序列化的基本误解,但无论如何......
我正在尝试序列化一个包含对象的类,该对象是使用 XMLSerializer 类通过数组初始化的。最小的例子:
using System;
using System.IO;
using System.Xml.Serialization;
namespace XMLSerializationTest
{
class Program
{
static void Main(string[] args)
{
try
{
string xmlFileName = Environment.CurrentDirectory + @"\somename.xml";
XmlSerializer writer = new XmlSerializer(typeof(MyClass));
FileStream file = File.Create(xmlFileName);
MyClass someclass = new MyClass();
writer.Serialize(file, someclass);
file.Close();
}
catch (Exception exc)
{
Console.WriteLine(exc);
}
Console.ReadLine();
}
}
public class MyClass
{
public object myObject;
public MyClass()
{
myObject = new string[1] { "somestring" };
}
}
}
但是,这会抛出 System.InvalidOperationException,这里不能使用读取数组。如果替换 MyClass 构造函数中的数组(例如,使用像这样的简单字符串),它就可以正常工作myObject = "somestring";
。不幸的是,我只是不知道我的对象是否是一个数组。那么有没有可能解决这个问题,例如使用属性还是 XML 在这种情况下是错误的方法?
你的困难源于以下事实:XmlSerializer
要求所有类型都序列化为可通过反射静态发现。然而,你的类型MyClass
具有多态性object
属性,其中子类型的实例object
- 具体来说string []
——正在存储中。什么时候XmlSerializer
遇到它,由于不需要这种类型的对象,序列化器会抛出您看到的异常。
当序列化诸如此类的多态属性时,有必要使用XML 序列化属性声明可以遇到的类型。XmlSerializer
提供了两种机制来实现这一点。
-
使用声明可能的多态亚型XmlInclude(Type)包含类型的属性。自从string
and string []
你的可能类型是object
财产,你会这样做:
[XmlInclude(typeof(string))]
[XmlInclude(typeof(string[]))]
public class MyClass
{
public object myObject { get; set; }
public MyClass()
{
myObject = new string[] { "somestring" };
}
}
结果 XML 将如下所示:
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<myObject xsi:type="ArrayOfString">
<string>somestring</string>
</myObject>
</MyClass>
注意xsi:type属性?这是一个w3c 标准属性允许元素显式断言其类型。它的存在使得XmlSerializer
将 XML 反序列化为与最初序列化时相同类型的对象。
(注意[XmlInclude(typeof(string))]
似乎没有必要,因为string
显然是一个内置的已知类型 - 尽管我找不到证实这一点的文档。)
-
使用声明可能的多态亚型[XmlElement(String, Type)]关于多态属性本身。因此你会做类似的事情:
public class MyClass
{
[XmlElement("myObjectString", typeof(string))]
[XmlElement("myObjectStringArray", typeof(string[]))]
public object myObject { get; set; }
public MyClass()
{
myObject = new string[] { "somestring" };
}
}
生成的 XML 将如下所示:
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<myObjectStringArray>
<string>somestring</string>
</myObjectStringArray>
</MyClass>
请注意,该名称的myObject
元素已修改为传递到的字符串[XmlElement(String, Type)]
属性构造函数。这允许XmlSerializer
将 XML 反序列化为与最初序列化时相同类型的对象。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)