Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not marked as serializable error when serializing a class

I am serializing an structure by using BinaryFormatter using this code:

private void SerializeObject(string filename, SerializableStructure objectToSerialize)
{
    Stream stream = File.Open(filename, FileMode.Create);
    BinaryFormatter bFormatter = new BinaryFormatter();
    bFormatter.Serialize(stream, objectToSerialize);
    stream.Close();
}

Which objectToSerialize is my structure, I'm calling this function like this:

SerializableStructure s = new SerializableStructure();
s.NN = NN;
s.SubNNs = SubNNs;
s.inputs = inputs;
SerializeObject(Application.StartupPath + "\\Save\\" + txtSave.Text + ".bin", s);

Which SerializableStructure, and Type of NN, SubNNs and inputs are serializable. (inputs contains some Points, Rectangles and generic lists).

Now, When I run my code, I am given this error:

Type 'MainProject.Main' in Assembly 'MainProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

Why I'm given this error? Main is my form, and these variables are located in my form.

I have successfully serialized Type of NN with MemoryStream and VB.NET , But I don't know why I'm getting this error?

Here is the definition of my structures:

SerializableStructure:

[Serializable()]
public class SerializableStructure
{
    public List<Inputs> inputs = new List<Inputs>();
    public NeuralNetwork NN;
    public NeuralNetwork[] SubNNs;
}

Inputs:

[Serializable()]
public class Inputs
{
    public string XPath { get; set; }
    public string YPath { get; set; }
    public string ImagePath { get; set; }
    public string CharName { get; set; }
    public string CharBaseName { get; set; }
    public List<double> x { get; set; }
    public List<double> y { get; set; }
    public List<double> DotsX { get; set; }
    public List<double> DotsY { get; set; }
    public List<Point> GravityCenters { get; set; }
    public List<Rectangle> Bounds { get; set; }

    public override string ToString()
    {
        return CharName;
    }

    public Inputs(string xPath, string yPath, string imagePath, string charName, string charBaseName)
    {
        XPath = xPath;
        YPath = yPath;
        ImagePath = imagePath;
        CharName = charName;
        CharBaseName = charBaseName;
        x = new List<double>();
        y = new List<double>();
        GravityCenters = new List<Point>();
        Bounds = new List<Rectangle>();
    }
}

Also NN is very big structure(!).

like image 637
Mahdi Ghiasi Avatar asked Dec 24 '11 11:12

Mahdi Ghiasi


People also ask

How do I make my AC class serializable?

The easiest way to make a class serializable is to mark it with the SerializableAttribute as follows. The following code example shows how an instance of this class can be serialized to a file. MyObject obj = new MyObject(); obj. n1 = 1; obj.

What is serializing in C#?

Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization.

How do you prevent a variable from being serialized in a serializable class?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

Can static class be serialized?

In Java, serialization is a concept using which we can write the state of an object into a byte stream so that we can transfer it over the network (using technologies like JPA and RMI). But, static variables belong to class therefore, you cannot serialize static variables in Java.


2 Answers

This almost alwas means you have an event (or other delegate - maybe a callback) somewhere in your object model, that is trying to be serialized. Add [NonSerialized] to any event-backing fields. If you are using a field-like event (the most likely kind), this is:

[field:NonSerialized] public event SomeDelegateType SomeEventName; 

Alternatively: most other serializers don't look at events/delegates, and provide better version-compatibility. Switching to XmlSerializer, JavaScriptSerializer, DataContractSerializer or protobuf-net (just 4 examples) would also solve this by the simple approach of not trying to do this (you almost never intend for events to be considered as part of a DTO).

like image 176
Marc Gravell Avatar answered Sep 22 '22 00:09

Marc Gravell


The problem is that you are trying to serialize a class derived from Form. The Form class is fundamentally unserializable. It has an enormous amount of internal state that is highly runtime dependent. That starts with an obvious property like Handle, a value that's always different. Less obvious are properties like Size, dependent on user preferences like the size of the font for the window caption. Ends with all the text, location and sizes for the controls, they are subject to localization. The odds that a serialized Form object can be properly deserialized anywhere at any time to create an exact clone of the form are zero.

Microsoft made no bones about it when they wrote the code, they simply omitted the [Serializable] attribute from the class declaration. Which is why you get the exception.

You'll have to aim lower, write your own class to capture your form's state. And give it the attribute. You'll need to write a bunch of code that maps between the form and control properties to an object of that class, back and forth.

like image 32
Hans Passant Avatar answered Sep 22 '22 00:09

Hans Passant