我在.NET中遇到了XmlSerializer的一些问题。
这里我有一个我刚刚建立的小例子。 (也可以@ gist https://gist.github.com/2d84be9041a3f9c06237)
using System.IO;
using System.Xml.Serialization;
namespace XmlSerializingSample
{
internal class Program
{
private static void Main(string[] args)
{
var specialType = new SpecialType()
{
Id = 1,
Name = "test"
};
var serializer = new XmlSerializer(typeof (SpecialType));
var des = new XmlSerializer(typeof (BaseType));
using (var memeStream = new MemoryStream())
{
serializer.Serialize(memeStream, specialType);
memeStream.Flush();
memeStream.Seek(0, SeekOrigin.Begin);
var instance = des.Deserialize(memeStream); // Here it throws the exception
}
}
}
[XmlInclude(typeof(SpecialType))]
[XmlType("baseType")]
public class BaseType
{
public long Id { get; set; }
}
[XmlRoot("special")]
public class SpecialType : BaseType
{
public string Name { get; set; }
}
}
在代码的第24行,我得到一个InvalidOperationException,声明“{”< special xmlns =''> wurde nicht erwartet。“}”[是的,这是德语]
我发现所有帖子都说明了,在反序列化的基类型上添加XmlIncludeAttribute后,这应该有效。我忘记了吗?
此致 的MacX
答案 0 :(得分:4)
问题是你的Serializer使用根元素序列化SpecialType:
<special ...>
<Id>...
但是你尝试使用var des = new XmlSerializer(typeof (BaseType));
反序列化它,它知道这两种类型,但它不知道如何处理xml中的root
元素。
如果您希望这样做,您还需要将基本类型的根元素设置为序列化为special
。换句话说,您需要这样做:
[XmlInclude(typeof(SpecialType))]
[XmlType("baseType")]
[XmlRoot("special")]
public class BaseType
{
public long Id { get; set; }
}
这样,反序列化器知道如何处理special
作为根元素。
我认为还有其他简单的替代品可以让这项工作开箱即用。
这是使用XmlAttributeOverrides类的另一种选择。
LinqPad代码:
void Main()
{
var specialType = new SpecialType()
{
Id = 1,
Name = "test"
};
var serializer = new XmlSerializer(typeof (SpecialType));
XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
XmlAttributes attrs = new XmlAttributes();
// Create an XmlRootAttribute to override.
XmlRootAttribute attr = new XmlRootAttribute();
attr.ElementName = "special";
// Add the XmlRootAttribute to the collection of objects.
attrs.XmlRoot=attr;
attrOverrides.Add(typeof(BaseType), attrs);
var des = new XmlSerializer(typeof (BaseType), attrOverrides);
using (var memeStream= new MemoryStream())
{
serializer.Serialize(memeStream, specialType);
memeStream.Flush();
memeStream.Seek(0, SeekOrigin.Begin);
var instance = des.Deserialize(memeStream);
}
}
[XmlInclude(typeof(SpecialType))]
[XmlType("baseType")]
public class BaseType
{
public long Id { get; set; }
}
[XmlRoot("special")]
public class SpecialType : BaseType
{
public string Name { get; set; }
}