Сериализация IEnumerable в котором ICollection

146
10 мая 2021, 14:10

У меня есть веб-приложение в котором я отображаются некоторые данные, я хочу с бд выгрузить данные в xml.

Вот модель

public class EmployeeDTO
{
    public int? Id { get; set; }
    public string Surname { get; set; }
    public string Name { get; set; }
    public string SecondName { get; set; }
    public string Position { get; set; }
    public IFormFile UploadedFile { get; set; }
    public string FilePath { get; set; }
    public ICollection<EmployeeTasksDTO> EmployeeTasks { get; set; }
}

Что бы выгрузить в xml я сначала считываю все данные в IEnumerable<EmployeeDTO> далее с помощь метода конвертирую IEnumerable<EmployeeDTO> в DataTable

protected DataTable ConvertToDataTable<T>(IEnumerable<T> collection)
    {
        DataTable dataTable = new DataTable();
        Type type = typeof(T);
        PropertyInfo[] propertyInfos = type.GetProperties();
        foreach(PropertyInfo property in propertyInfos)
        {
            dataTable.Columns.Add(property.Name, Nullable.GetUnderlyingType(
        property.PropertyType) ?? property.PropertyType);
        }
        foreach(T item in collection)
        {
            DataRow dataRow = dataTable.NewRow();
            dataRow.BeginEdit();
            foreach(PropertyInfo property in propertyInfos)
            {
                dataRow[property.Name] = property.GetValue(item, null);
            }
            dataRow.EndEdit();
            dataTable.Rows.Add(dataRow);
        }
        dataTable.TableName = $"{type.Name}_details";
        return dataTable;
    }

Так как таких списков 3, я сделал этот метод дженерик один список в котором IEnumerable == null выгружается в XML без проблем Но остальные с ошибкой

System.InvalidOperationException: 'Type 'System.Collections.Generic.List`1[[BLayer.DTO.EmployeeTasksDTO, BLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' does not implement IXmlSerializable interface therefore can not proceed with serialization.

Как мне исправить это?

protected void WriteAndSaveXMLFile(DataTable dataTable)
    {
        string filePath = Path.Combine(AppSetting.SetXMLFilesPath(), dataTable.TableName);
        using (XmlTextWriter writer = new XmlTextWriter(filePath, null))
        {
            writer.Formatting = Formatting.Indented;
            dataTable.WriteXml(writer);
        }
    }
Answer 1

попробуйте так

WriteAndSaveXMLFile<T>(IEnumerable<T> entities, string filePath)
{    
    var serializer = new XmlSerializer();
    using (var stream = File.OpenWrite(filePath))
    {
        serializer.Serialize(stream, entities);
    }
}

Написал без возможности проверить, так что, возможно, придется отладить.

Answer 2

Сделал так с помощью DataContractSerializer serializer = new DataContractSerializer(type) теперь все окей

public MemoryStream Export(IEnumerable<T> collection)
        {
            Type type = collection.GetType();
            var stream = new MemoryStream();
            DataContractSerializer serializer = new DataContractSerializer(type);
            using (XmlTextWriter writer = new XmlTextWriter(stream, null))
            {
                writer.Formatting = Formatting.Indented;
                foreach (var item in collection)
                {
                    serializer.WriteObject(writer, item);
                }
            }
            return stream;
        }
READ ALSO
PyMySQL как сделать insert?

PyMySQL как сделать insert?

Вот код моего парсера

109
поиск со стеммером

поиск со стеммером

вопрос в тормозах при нескольких словах одновременно

110
Как объединить (просуммировать) данные в столбце по id?

Как объединить (просуммировать) данные в столбце по id?

У меня есть таблица со следующими данными:

91
Laravel, получение body params action-а

Laravel, получение body params action-а

Хочу написать пакет для автогенерации сваггера, или что-то вроде того

113