0

I am trying to serialize a class object and ran into a problem when I added a System.Timers.Timer object.

During serialization, I am getting the following exception:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll

Additional information: Type 'System.Timers.Timer' in Assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

The project is .net 4.6 Windows Forms application

Here is the class I am serializing:

using System;
using System.Xml.Serialization;

[Serializable]
[XmlInclude(typeof(CTestClass))]
public class CTestClass
{
    public CTestClass()
    {
        x = 1;
        timer = new System.Timers.Timer();
    }

    [XmlElement]
    public int x { get; set; }

    // It seems [XmlIgnore] is being ignored... :-(
    [XmlIgnore]
    public System.Timers.Timer timer { get; set; }
}

Here is the code that I am using to serialize the class object:

( NOTE: use of the BinaryFormatter is required )

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;

    private void TestIt()
    {
        CTestClass ctc = new CTestClass();
        SerializeData(ctc);
    }

    protected virtual byte[] SerializeData(CTestClass data)
    {
        using (var memoryStream = new MemoryStream())
        {
            new BinaryFormatter().Serialize(memoryStream, data);
            return memoryStream.ToArray();
        }
    }

From the Comments:

Setting the property to private - didn't help

    private System.Timers.Timer timer { get; set; }

using [NonSerialized] - didn't help:

Error   CS0592  Attribute 'NonSerialized' is not valid on this declaration type. It is only valid on 'field' declarations.  TimerSerializationError c:\TimerSerializationError\TimerSerializationError\CTestClass.cs    19  Active

"specifically not using an auto-property--(i.e. no get-set)" - didn't help:

 Additional information: Type 'System.Timers.Timer' in Assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
  • 1
    You're not using XML serialization, that's why the `[XmlIgnore]` attribute is being ignored. Just make your timer `private` - it's unlikely that you'd want to expose it anyway. – Simon MᶜKenzie Nov 02 '16 at 21:41
  • Changed the timer to private -- SAME error – George Winters Nov 02 '16 at 21:57
  • Sorry about that. Perhaps you could use an XmlSerializer instead, or remove the timer from your class, or maybe have your class hold an instance of a "settings" class, which contains the real serializable data, and just serialize/deserialise the settings class instead. Finally, you could also choose to implement `ISerializable`, in which case you can control what's included in serialization. – Simon MᶜKenzie Nov 02 '16 at 22:04

2 Answers2

0

It's the [Serializable] attribute that's getting you.

Because you're using the [Serializable] attribute, you'll want to add [NonSerialized] for your timer property, as detailed in this answer.

Community
  • 1
  • 1
UtopiaLtd
  • 2,520
  • 1
  • 30
  • 46
  • Severity Code Description Project File Line Suppression State Error CS0592 Attribute 'NonSerialized' is not valid on this declaration type. It is only valid on 'field' declarations. TimerSerializationError c:\TimerSerializationError\TimerSerializationError\CTestClass.cs 19 Active – George Winters Nov 02 '16 at 21:56
  • I don't want it serialized ... at all – George Winters Nov 02 '16 at 22:00
  • Right, but try specifically not using an auto-property--(i.e. no get-set). Do the backing field (`private System.Timers.Timer timer;`) , put `[NonSerialized]` on that, and then write a public property with getter and setter that points to your backing field if you still need that. – UtopiaLtd Nov 02 '16 at 22:10
  • NonSerialized is not allowed as a property decorator – George Winters Nov 02 '16 at 22:14
  • Right, the `[NonSerialized]` goes on the field and the `[XmlIgnore]` goes on the property. – UtopiaLtd Nov 02 '16 at 22:21
  • Please read : http://stackoverflow.com/questions/7693391/nonserialized-on-property – George Winters Nov 02 '16 at 22:25
  • Yes. See the chosen answer for that--if we were that question, `[NonSerialized]` goes on the private field `list` while `[XmlIgnore]` goes on the public property `paramFiles`. – UtopiaLtd Nov 02 '16 at 22:28
0

Here is what I had to do to ~totally~ ignore the timer object :

[Serializable]
public class CTestClass : ISerializable
{
    public CTestClass()
    {
        x = 1;
        timer = null;
    }

    public int x { get; set; }

    private System.Timers.Timer timer { get; set; }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("x", x);
    }
}