序列化使用DataContractSerializer在列表列表上失败

时间:2012-03-22 06:50:40

标签: c# .net xml-serialization datacontractserializer

我有一些类具有List<object>类型的属性我需要使用DataContractSerializer将该类序列化为XML文件。

当对象是ArgumentException异常消息时,List<T>/IEnumerator<T>上的序列化失败:

  

中的姓名字符无效   'System.Collections.Generic.List`1 [[MyProj.Result,MyProj,   Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]'。

以下是失败的代码示例 采用List<object>

的类
[DataContract(IsReference = true)]
    public class RecoveryMethodData
    {
        [DataMember]
        public List<object> Parameters { get; set; }


        public RecoveryMethodData()
        {
            Parameters = new List<object>();
        }

        public static void SerializeToFile(RecoveryMethodData recoveryMethodData, string fileName)
        {
            var encoding = Encoding.UTF8;
            using (var fileWriter = new XmlTextWriter(fileName, encoding))
            {

                fileWriter.Formatting = Formatting.Indented;
                // use SharedTypeResolver for deserializing assistance.
                var serializer = new DataContractSerializer(typeof(RecoveryMethodData), null, int.MaxValue, false, true, null, new SharedTypeResolver());
                serializer.WriteObject(fileWriter, recoveryMethodData);
            }
        }
}

以下是用法:

private void TestSerialization()
{
    var methodData = new RecoveryMethodData();
    var result = new Result() {Message = "wow", Pass = true, FileName = "somefile "};
    methodData.Parameters.Add(result);
    methodData.Parameters.Add(true);
    var list1 = new List<Result>();
    list1.Add(new Result(){FileName = "in list1", Message = "in l 1"});
    list1.Add(new Result(){FileName = "in list2", Message = "in l 2"});
    methodData.Parameters.Add(list1);
    RecoveryMethodData.SerializeToFile(methodData,@"C:\serialization_result.xml");
}
public class Result
{
    public string Message { get; set; }
    public string FileName { get; set; }
}

如果我没有将list1添加到methodData.Parameters中,则序列化methodDatad对象没有问题。

一个很大的限制是我无法事先知道将哪种对象添加到Parameters属性(这就是为什么它是一个对象列表)

1 个答案:

答案 0 :(得分:0)

为了使DataContractSerializer序列化一个对象,它应该知道所有数据库的类型。在您的情况下,您不定义特定类型,而是定义对象类型。尝试更改

的定义
public List<object> Parameters { get; set; }

类似于:

public List<IMyObject> Parameters { get; set; }

请注意,您尝试添加到参数列表的所有对象都应继承IMyObject接口。

更新:我在某些方面重构了你的代码(仍然形状不好),看起来有效,请试一试;

public class Tester 
{
    public Tester()
    {
        this.TestSerialization();

    }

    public void SerializeToFile(RecoveryMethodData recoveryMetaData,string fileName)
    {
        var encoding = Encoding.UTF8;
        using (var fileWriter = new XmlTextWriter(fileName, encoding))
        {

            fileWriter.Formatting = Formatting.Indented;
            // use SharedTypeResolver for deserializing assistance.
            var serializer = new DataContractSerializer(typeof(RecoveryMethodData),new List<Type>(){typeof(bool),typeof(Result),typeof(List<Result>)});                
            serializer.WriteObject(fileWriter,recoveryMetaData);
        }
    }

    private void TestSerialization()
    {
        var methodData = new RecoveryMethodData();
        var result = new Result() { Message = "wow", Pass = true, FileName = "somefile " };
        methodData.Add(result);
        methodData.Add(true);
        var list1 = new List<Result>();
        list1.Add(new Result() { FileName = "in list1", Message = "in l 1" });
        list1.Add(new Result() { FileName = "in list2", Message = "in l 2" });
        methodData.Add(list1);
        SerializeToFile(methodData, @"C:\serialization_result.xml");
    }
}

public class Result
{
    public string Message { get; set; }
    public string FileName { get; set; }
    public bool Pass { get; set; }
}


public class RecoveryMethodData : List<object>
{

}