0

Hopefully this question isn't too obvious, however I'm taking my first steps into the topic of serialization and couldn't find an explanation for the following behaviour:

I wanted to serialize a class to test if I set up everything correctly. For this I took the code from this tutorial and adapted it as follows:

    private void SerializePresets(string path)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyClass));
        using (TextWriter writer = new StreamWriter(path))
        {
            xmlSerializer.Serialize(writer, this);
        }
    }

This method lies within MyClass and is also called from there. This gives me the following exception:

An exception of type 'System.InvalidOperationException' occurred in System.Xml.dll but was not handled in user code

Additional information: There was an error reflecting type 'MyClass'.

Since MyClass holds other class object as properties first I thought I have to make those serializabel too, however the exception still persists. So, my guess is, that it is impossible serialize this, however I couldn't find a confirmation to this guess.

EDIT: This property causes the issue according to the inner exception:

[XmlArray("VolumePresetList"), XmlArrayItem(typeof(LinearAxisColorPresetsModel), ElementName = "VolumePresetList")]
public ObservableCollection<LinearAxisColorPresetsModel> VolumePresetList { get; set; }
Roland Deschain
  • 2,211
  • 19
  • 50

2 Answers2

1

You can use this. It must be one of the properties like a Dictionary that doesn't serialize. See my example below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication103
{
    class Program
    {

        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            myClass.Serialize(FILENAME);

        }
    }
    public class MyClass
    {
         public string test { get; set; }

         public void Serialize(string filename)
         {
             SerializePresets(filename);
         }
         private void SerializePresets(string path)
         {
             XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyClass));
             using (TextWriter writer = new StreamWriter(path))
             {
                 xmlSerializer.Serialize(writer, this);
             }
        }
    }

}
jdweng
  • 33,250
  • 2
  • 15
  • 20
1

With the help of the inner exceptions (thanks for the tip again) I could find out the reason why the serialization failed.

The class LinearAxisColorPresetsModeldid not have a parameterless Constructor, which caused this issue.

Simply adding

/// <summary>
/// Default Constructor
/// </summary>
private LinearAxisColorPresetsModel()
{

}

to this class solved the problem for me. What remains is to find out the reason, why we must have a parameterless Constructor.

EDIT: Found the reasoning behind this behaviour in this post.

Roland Deschain
  • 2,211
  • 19
  • 50
  • Interestingly Boost serialisation for C++ also needs classes to have a parameterless constructor. In that it's because deserialisation works in a similar way to that described in the link you've added. I guess this is necessary for serialisation that is not an inherent part of the language (XML for C#, Boost for C++); as a library it has no knowledge of how an object get layed out in memory, and so has use the constructor to create it. At least in C# the setters can do useful things. In C++ there are no setters, and so post-deserialisation work has to be called manually; room for errors... – bazza Mar 01 '19 at 21:16