Ошибка сериализации в списке списков с использованием DataContractSerializer - PullRequest
0 голосов
/ 22 марта 2012

У меня есть некоторый класс со свойством типа List<object> Мне нужно сериализовать этот класс в файл XML, используя DataContractSerializer.

Сериализация не удалась на ArgumentException, когда объект является List<T>/IEnumerator<T> сообщение об исключении:

Недопустимый символ имени в 'System.Collections.Generic.List`1 [[MyProj.Result, MyProj, версия = 1.0.0.0, культура = нейтральная, 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 голосов
/ 22 марта 2012

Чтобы 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>
{

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...