views:

714

answers:

3

I get a SerializationException: (...) is not marked as serializable. error in the following code:

[Serializable]
public class Wind
{
    public MyText text;
    public Size MSize;
    public Point MLocation;
    public int MNumber;

    /.../
}

[Serializable]
public class MyText 
{
    public string MString;
    public Font MFont;
    public StringFormat StrFormat;
    public float MySize;
    public Color FColor, SColor, TColor;
    public bool IsRequest;
    public decimal MWide;

    /.../
}

and the List to be serialized:

 List<Wind> MyList = new List<Wind>();

Code Snippet:

 FileStream FS = new FileStream(AppDomain.CurrentDomain.BaseDirectory + 
                                "Sticks.dat", FileMode.Create);
 BinaryFormatter BF = new BinaryFormatter();

 BF.Serialize(FS, MyList);  
 FS.Close();

throws an Exception:

System.Runtime.Serialization.SerializationException was unhandled
  Message="Type 'System.Drawing.StringFormat' in Assembly 'System.Drawing,   
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not 
marked as serializable."

How do I solve this problem?

+2  A: 

Any item that cannot be serialized can be marked as not serializable by applying the [NotSerialized] attribute. This does mean though that you have to recreate the type explicitly, rather than relying on the serializer recreating it.

Pete OHanlon
+1 good point. If the "StrFormat" has to be serialized after all, one could e.g. create a separate property that just contains a string representation of it. Needs some work on deserialization, too, in that case
marc_s
A: 

Looks like you'll have to role you're own form of serialisation, or wrap the class in something that can be serialised. If you create an implicit cast, the user of your class won't even notice in some situations...

To get your class to serialise as it stands, you'll have to add the NonSerialized attribute to the StrFormat property.

Kieron
+2  A: 

With BinaryFormatter, you can exclude a field by marking it [NonSerialized], but then you won't get the data. You could use custom serialization (ISerializable), but that is hard.

Personally, I'd use a different serializer; in particular, DataContractSerializer or protobuf-net, either of which allows you to create a second property to use for the serialization, writing your own code to represent it as something simpler (a string, perhaps).

Marc Gravell
+1, not heard of protobuf-net, sounds useful.
Pondidum