Reputation: 3845
I am trying to serialize an IEnumerable<FileInfo>
into xml. I have researched and found that because the FileInfo class does not have a parameterless constructor, it cannot be serialized as it is, and i should use a wrapper class.
For simplicity, the code im using to serialize is in the click event of a winforms button as shown. Ill refactor this once its working:
private void button1_Click(object sender, System.EventArgs e)
{
IEnumerable<FileInfo> allfiles = FileGetter.FileInfoAllFiles();
FileList filelist = new FileList();
foreach (var file in allfiles)
{
filelist.Add(new FileInfoSerializable(file));
}
var stream = new FileStream("Xmllist.xml", FileMode.Create);
new XmlSerializer(typeof(FileInfoSerializable)).Serialize(stream, filelist);
}
The wrapper class:
[Serializable]
public class FileInfoSerializable
{
private readonly FileInfo _fileInfo;
#region ~~~ Constructors ~~~
public FileInfoSerializable() { }
public FileInfoSerializable(FileInfo FileInfo) { _fileInfo = FileInfo; }
#endregion
#region ~~~ Properties ~~~
public string Name { get { return _fileInfo.Name; } set { } }
public string FullName { get { return _fileInfo.FullName; } set { } }
public long Length { get { return _fileInfo.Length; } set { } }
public string Extension { get { return _fileInfo.Extension; } set { } }
public DateTime LastWriteTime { get { return _fileInfo.LastWriteTime; } set { } }
public string DirectoryName { get { return _fileInfo.DirectoryName; } set { } }
#endregion
}
I want to add each FileInfo object in the IEnumerable<FileInfo>
to a collection, which i will then serialize.This is the class that holds the collection:
[Serializable]
public class FileList
{
public List<FileInfoSerializable> filez { get; set; }
public FileList()
{
filez = new List<FileInfoSerializable>();
}
public void Add(FileInfoSerializable m)
{
filez.Add(m);
}
}
THE PROBLEM
Im getting the following exception at the line: new XmlSerializer(typeof(FileInfoSerializable)).Serialize(stream, filelist);
I have tried casting to a generic list, using filelist.filez in place of filelist but still getting the same error. What do i need to change to make this work?
cheers
Upvotes: 4
Views: 2158
Reputation: 1
I have used your code to serialize and it works correctly, but when I Deserialize the List 'filez' has items, but each item is void (null).
This is the code for deserialize:
if (System.IO.File.Exists(fullName))
{
var stream = new FileStream(fullName, FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(FileList));
//var filelista = serializer.Deserialize(stream);
filelist = (FileList)serializer.Deserialize(stream);
}
I attach debug info:
Upvotes: 0
Reputation: 34421
I finally found issue. typeof(FileInfoSerializable) should be typeof(FileList). The code below works. FileInfoSerializable was creating an array at the root level of the xml. The root of the xml must be singular.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication49
{
class Program
{
static void Main(string[] args)
{
List<FileInfo> allfiles = Directory.GetFiles(@"c:\temp").Select(x => new FileInfo(x)).ToList();
FileList filelist = new FileList();
foreach (var file in allfiles)
{
filelist.Add(new FileInfoSerializable(file));
}
var stream = new FileStream("c:\\temp\\Xmllist.xml", FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(FileList));
serializer.Serialize(stream, filelist);
}
}
[Serializable]
public class FileInfoSerializable
{
private readonly FileInfo _fileInfo;
#region ~~~ Constructors ~~~
public FileInfoSerializable() { }
public FileInfoSerializable(FileInfo FileInfo) { _fileInfo = FileInfo; }
#endregion
#region ~~~ Properties ~~~
public string Name { get { return _fileInfo.Name; } set { } }
public string FullName { get { return _fileInfo.FullName; } set { } }
public long Length { get { return _fileInfo.Length; } set { } }
public string Extension { get { return _fileInfo.Extension; } set { } }
public DateTime LastWriteTime { get { return _fileInfo.LastWriteTime; } set { } }
public string DirectoryName { get { return _fileInfo.DirectoryName; } set { } }
#endregion
}
[Serializable]
public class FileList
{
public List<FileInfoSerializable> filez { get; set; }
public FileList()
{
filez = new List<FileInfoSerializable>();
}
public void Add(FileInfoSerializable m)
{
filez.Add(m);
}
}
}
Upvotes: 1