ForwardedTypesSerializationBinder Class
Provides a
SerializationBinder that makes possible to serialize and deserialize types with custom assembly identity.
Namespace: KGySoft.Serialization.BinaryAssembly: KGySoft.CoreLibraries (in KGySoft.CoreLibraries.dll) Version: 8.1.0
public sealed class ForwardedTypesSerializationBinder : SerializationBinder,
ISerializationBinder
Public NotInheritable Class ForwardedTypesSerializationBinder
Inherits SerializationBinder
Implements ISerializationBinder
public ref class ForwardedTypesSerializationBinder sealed : public SerializationBinder,
ISerializationBinder
[<SealedAttribute>]
type ForwardedTypesSerializationBinder =
class
inherit SerializationBinder
interface ISerializationBinder
end
- Inheritance
- Object SerializationBinder ForwardedTypesSerializationBinder
- Implements
- ISerializationBinder
If a deserialization stream may come from an untrusted source, then make sure to set the SafeMode property
to to prevent loading assemblies and resolving any types but the explicitly specified ones.
See the security notes at the Remarks section of the BinarySerializationFormatter class for more details.
Without specifying any expected types the ForwardedTypesSerializationBinder does nothing special. Resolving types from legacy
assemblies works automatically if at least a chunk version of the assembly exists on the current platform containing nothing but a bunch
of TypeForwardedToAttribute attributes (this is the case for the original .NET Framework assemblies on .NET Core and .NET Standard).
To resolve types that are not forwarded by the TypeForwardedToAttribute from an existing assembly with the
given identity you can use this binder for deserialization. Add the types to be handled by the AddType or
AddTypes methods.
If WriteLegacyIdentity is set to , then mapping works also on serialization.
For types without an explicitly set mapping the value of the TypeForwardedFromAttribute attribute will be written if it is defined.
By default, both
BinaryFormatter and
BinarySerializationFormatter dumps legacy identities on serialization
for types decorated by the
TypeForwardedFromAttribute. If you use this binder on serialization without adding any type
just after setting the
WriteLegacyIdentity to
, then the only difference will be that even the
mscorlib assembly
name will be dumped to the output stream, which would be omitted otherwise.
To serialize types with arbitrary assembly identity, use this binder both for serialization and deserialization.
Add the type to be handled by the AddType method and specify at least one AssemblyName
for each added Type.
The following example demonstrates the usage of the ForwardedTypesSerializationBinder when types have to be deserialized from a stream,
which have been originally serialized by another version of the assembly.
// If SafeMode is true you must declare every type name that can occur in the serialization stream;
// otherwise, just the ones with changed identity.
var binder = new ForwardedTypesSerializationBinder { SafeMode = true };
// MyType will be able to be deserialized if the assembly name in the
// serialization stream matches any of the enlisted ones.
binder.AddType(typeof(MyType),
new AssemblyName("MyOldAssembly, Version=1.0.0.0"),
new AssemblyName("MyOldAssembly, Version=1.2.0.0"),
new AssemblyName("MyNewAssembly, Version=1.5.0.0"),
new AssemblyName("MyNewAssembly, Version=2.0.0.0"));
// MyOtherType will be able to be deserialized if it was serialized by any versions of MyAssembly.
binder.AddType(typeof(MyOtherType), new AssemblyName("MyAssembly"));
// Any type of any assembly will be mapped to SomeOtherType if their full names match.
binder.AddType(typeof(SomeOtherType));
// Multiple types can be enlisted without assembly identity
binder.AddTypes(typeof(MyType), typeof(MyOtherType), typeof(SomeOtherType));
IFormatter formatter = new BinarySerializationFormatter { Binder = binder }; // or BinaryFormatter
object result = formatter.Deserialize(serializationStream);
The
WeakAssemblySerializationBinder is also able to ignore assembly information but if there are two different
types of the same name in the same namespace, then the behavior of
WeakAssemblySerializationBinder is not deterministic.
The following example demonstrates how to control the serialized assembly name.
// Setting the WriteLegacyIdentity allows to use arbitrary custom indenity on serialization.
var binder = new ForwardedTypesSerializationBinder { WriteLegacyIdentity = true };
// When serializing a MyType instance, it will be saved with the firstly specified identity
binder.AddType(typeof(MyType),
new AssemblyName("MyOldAssembly, Version=1.0.0.0"),
new AssemblyName("MyOldAssembly, Version=1.2.0.0"),
new AssemblyName("MyNewAssembly, Version=1.5.0.0"),
new AssemblyName("MyNewAssembly, Version=2.0.0.0"));
// If WriteLegacyIdentity is true, types with TypeForwardedFromAttribute will be automatically written
// with their old identity stored in the TypeForwardedFromAttribute.AssemblyFullName property.
// List<T> has a TypeForwardedFromAttribute in .NET Core and Standard so it will be serialized with
// mscorlib assembly identity in every platform:
var obj = new List<MyType> { new MyType() };
IFormatter formatter = new BinaryFormatter { Binder = binder }; // or BinarySerializationFormatter
formatter.Serialize(serializationStream, obj);
If not only the assembly name but also the inner content of a type (ie. field names) changed, then you can use
the
CustomSerializerSurrogateSelector class.
SafeMode |
Gets or sets whether all of the type names that occur in the serialization stream must have a defined mapping to a type.
Default value: .
|
WriteLegacyIdentity |
Gets or sets whether a legacy assembly identity is tried to be written on serializing.
Default value: .
|