XmlSerializer/Deserialize in C#

631 views Asked by At

I created this class where it'll append to the XML called Email Alerts h1, body and ids. However, im having trouble running this file from the start (when i call LoadFromFile), when the file does not exist - so we'll have to create a file and start logging it.

public class EMailAlert
{
    public string h1 { get; set; }
    public string body { get; set; }
    public string idList { get; set; }

    public void Save(string fileName)
    {
        using (var stream = new FileStream(fileName, FileMode.Create))
        {
            var XML = new XmlSerializer(typeof(EMailAlert));
            XML.Serialize(stream, this);
        }
    }

    public static EMailAlert LoadFromFile(string fileName)
    {
        if (!File.Exists(fileName))
        {
            var file = new FileInfo(fileName);
            file.Directory.Create();
            var xmlFile = new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"),
            new XComment("Email Logger"));
            xmlFile.Add(new XElement("EmailAlerts"));
            xmlFile.Save(fileName);
        }
        using (var stream = new FileStream(fileName, FileMode.Open))
        {
            var XML = new XmlSerializer(typeof(EMailAlert));
            return (EMailAlert)XML.Deserialize(stream);
        }
    }
}

When i run this code (there are no xml file - so it creates an XML file and then it throws this error {"<EmailAlerts xmlns=''> was not expected."}

Here is how the xml file looks like

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--Email Logger-->
<EmailAlerts />

Not sure why its not sending back an empty EmailAlert when i call LoadFromFile.

1

There are 1 answers

0
rene On BEST ANSWER

You need a collectiontype for your all your EMailAlerts to be serialized as valid xml.

The following code does that. By creating a static helper class that holds a static List of all our EmailAlerts. It also has the Load and Save methods which reads and writes the file and use the property Alerts to get or store the EmailAlerts.

You can use attributes on your EmailAlert class if you want to control serialization. See this answer how you could do that.

public static class EMailAlerts
{
    static XmlSerializer   XML = new XmlSerializer(typeof(List<EMailAlert>));

    public static List<EMailAlert> Alerts { get; private set; }

    public static void Save(string fileName)
    {
        using (var stream = new FileStream(fileName, FileMode.Create))
        {
            XML.Serialize(stream, Alerts);
        }
    }

    public static void LoadFromFile(string fileName)
    {
        if (!File.Exists(fileName))
        {
            Alerts = new List<EMailAlert>();
        }
        else
        {
            using (var stream = new FileStream(fileName, FileMode.Open))
            {
                Alerts = (List<EMailAlert>)XML.Deserialize(stream);
            }
        }
    }
}

public class EMailAlert
{
    public string h1 { get; set; }
    public string body { get; set; }
    public string idList { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        EMailAlerts.LoadFromFile("tmp.xml");

        EMailAlerts.Alerts.Add(new EMailAlert{ body="foo"});
        EMailAlerts.Save("tmp.xml"); 
    }
}