- Serialization is the process of converting an object into a stream of bytes in order 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.
- Basic serialization uses the .NET Framework to automatically serialize the object.
System.Runtime.Serialization
contains the classes necessary for serializing and deserializing objects.
- The only requirement in basic serialization is that the object has the
Serializable
attribute applied.
- The
Serializable
attribute cannot be inherited. If you derive a new class from a base class, the new class must be marked with the attribute as well.
- The
NonSerialized
can be used to keep specific fields from being serialized.
- If a field of a serializable type contains a pointer, a handle, or some other data structure that is specific to a particular environment, and the field cannot be meaningfully reconstituted in a different environment, then you may want to make it non-serializable by mark the field with
NonSerialized
attribute.
- If a serialized class contains references to objects of other classes that are marked
Serializable
, those objects will also be serialized.
- A
SerializationException
exception is thrown if you attempt to serialize but the type does not have the Serializable
attribute.
- When you use basic serialization, the versioning of objects may create problems, in which case custom serialization may be preferable.
- Basic serialization is the easiest way to perform serialization, but it does not provide much control over the process.
- In custom serialization, you can specify exactly which objects will be serialized and how it will be done.
- You can influence the serialization and deserialization process when starting and finishing an action by defining methods decorated with the following attributes:
[Serializable]
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
[NonSerialized]
private bool isDirty = false;
[OnSerializing]
internal void OnSerializingMethod(StreamingContext context) { }
[OnSerialized]
internal void OnSerializedMethod(StreamingContext context) { }
[OnDeserializing]
internal void OnDeserializingMethod(StreamingContext context) { }
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context) { }
}
- Serialized object could expose private data that is security sensitive.
- If you have a sensitive class, you should implement the
ISerializable
interface.
- When implementing this interface, you have control over which values are serialized.
- You could choose to not serialize sensitive data or possibly encrypt prior to serialization.
- Implementing
ISerializable
consists of two important parts:
- The
GetObjectData
method is called when your object is serialized.
- It should add the values that you want to serialize as key/value pairs to the
SerializationInfo
object that’s passed to the method.
- Mark this method with a
SecurityPermission
attribute (System.Security.Permissions
) so that it is allowed to execute serialization and deserialization code.
- Add a special protected constructor that takes a
SerializationInfo
and StreamingContext
.
- This constructor is called during deserialization, and you use it to retrieve the values and initialize your object.
[Serializable]
public class PersonComplex : ISerializable
{
public int Id { get; set; }
public string Name { get; set; }
private bool isDirty = false;
public PersonComplex() { }
protected PersonComplex(SerializationInfo info, StreamingContext context)
{
Id = info.GetInt32("Value1");
Name = info.GetString("Value2");
isDirty = info.GetBoolean("Value3");
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Value1", Id);
info.AddValue("Value2", Name);
info.AddValue("Value3", isDirty);
}
}
- Binary serialization uses binary encoding to produce compact serialization for uses such as storage or socket-based network streams.