XmlSerializer System.InvalidOperationException

时间:2015-01-20 11:50:20

标签: c# xmlserializer invalidoperationexception

我的应用程序中有以下代码:

[Serializable]
public class Class
{
    private string name = "";
    private List<Property> property = new List<Property>();
    [XmlAttribute]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    [XmlArray(ElementName = "Properties")]
    public List<Property> Property
    {
        get { return property; }
        set { property = value; }
    }
    public Class() { }
}
[Serializable]
public class Property
{
    private string name = "";
    private object value;

    [XmlAttribute]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    [XmlElement]
    public object Value
    {
        get { return this.value; }
        set { this.value = value; }
    }
    public Property() { }
}
class Program
{
    static void Main(string[] args)
    {
        List<Class> classList = GetClassList();
        SerializeConfig("test.xml", classList);
    }
    private static List<Class> GetClassList()
    {
        return new List<Class>(){
            new Class()
            {
                Name = "MyFirstClass",
                Property = new List<Property>() {
                    new Property(){ Name = "StringProperty",    Value = "Simple1"},
                    new Property(){ Name = "IntProperty",       Value = 3},
                    new Property(){ Name = "DoubleProperty",    Value = 5.5},
                    new Property(){ Name = "ListProperty",      Value = new List<int>(){
                        1,2,3,4,5
                        }
                    },
                }
            }
        };
    }
    public static List<Class> DeserializeConfig(string configPath)
    {
        if (!File.Exists(configPath)) return null;
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Class>), new XmlRootAttribute("Classes"));
            using (FileStream fs = File.Open(configPath, FileMode.Open))
            {
                return (List<Class>)serializer.Deserialize(fs);
            }
        }
        catch (Exception)
        {
            return null;
        }
    }
    public static bool SerializeConfig(string path, List<Class> config)
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Class>), new XmlRootAttribute("Classes"));
            using (FileStream fs = File.Open(path, FileMode.Create))
            {
                serializer.Serialize(fs, config);
            }
        }
        catch (Exception)
        {
            return false;
        }
        return true;
    }
}

如果您运行此代码,则会收到System.InvalidOperationException,其中包含以下消息:

{System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] may not be used in this context.
   at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterList1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterList1.Write2_Property(String n, String ns, Property o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterList1.Write3_Class(String n, String ns, Class o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterList1.Write4_Classes(Object o)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o, XmlSerializerNamespaces namespaces)
   at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o)
   at SerializeTest.Program.SerializeConfig(String path, List`1 config) in [...]\Program.cs:line 102}

为什么我不能以这种方式序列化List?我如何建立一个变通方法?

2 个答案:

答案 0 :(得分:1)

好的,我找到了解决方案。我必须添加自定义类型。

XmlSerializer serializer = new XmlSerializer(typeof(List<Class>), null, new Type[] { typeof(List<int>) }, new XmlRootAttribute("Classes"),"");

所以我必须从我的列表中收集所有类型:

private static Type[] CollectTypesFromCollection(List<Class> collection)
{
    List<Type> types = new List<Type>();
    foreach (Class item in collection)
        foreach (Property property in item.Property)
            if (!types.Contains(property.Value.GetType()))
                types.Add(property.Value.GetType());
    return types.ToArray();
}

可以像这样使用序列化器:

XmlSerializer serializer = new XmlSerializer(typeof(List<Class>),null,CollectTypesFromCollection(config), new XmlRootAttribute("Classes"),"");

答案 1 :(得分:-1)

由于XML Serialization创建的方式,我建议您在进入发生错误的List之前先查看一下。

Introducing XML Serialization

参考:XmlSerializer List Item Element Name