.Net binary serialization version tolerant
Hi.
I have serialized an object of the class:
[Serializable]
public class ToolParameterEdit
{
protected ToolParameterEdit()
{
Initialize();
}
public CustomObservableCollection<ToolClasses> Classes { get; set; }
private void Initialize()
{
Classes = new CustomObservableCollection<ToolClasses>
{
IsReadOnly = () => this.IsReadOnly
};
}
}
If I modify the class on
[Serializable]
public class ToolParameterEdit : ISerializable
{
protected ToolParameterEdit()
{
Initialize();
}
public CustomObservableCollection<ToolClasses> Classes { get; set; }
public CustomObservableCollection<ToolTwinTypes> TwinTypes { get; set; }
private void Initialize()
{
Classes = new CustomObservableCollection<ToolClasses>
{
IsReadOnly = () => this.IsReadOnly
};
TwinTypes = new CustomObservableCollection<ToolTwinTypes>
{
IsReadOnly = () => this.IsReadOnly
};
}
protected ToolParameterEdit(SerializationInfo info, StreamingContext context)
{
Classes = (CustomObservableCollection<ToolClasses>)info.GetValue("<Classes>k__BackingField", typeof(CustomObservableCollection<ToolClasses>));
TwinTypes = Misc.TryGetSerializedVariableValue(info, nameof(TwinTypes), () => new CustomObservableCollection<ToolTwinTypes>());
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(Classes), Classes);
info.AddValue(nameof(TwinTypes), TwinTypes);
}
}
there is the issue when I deserialize the stream with first version of class, I receave an exception like this:
System.Runtime.Serialization.SerializationException
HResult=0x8013150C
Message=Cannot get the member '<Initialize>b__29_0'.
Source=mscorlib
StackTrace:
at System.Reflection.MemberInfoSerializationHolder.GetRealObject(StreamingContext context) in f:\dd\ndp\clr\src\BCL\system\reflection\memberinfoserializationholder.cs:line 282
at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder) in f:\dd\ndp\clr\src\BCL\system\runtime\serialization\objectmanager.cs:line 302
at System.Runtime.Serialization.ObjectManager.DoFixups() in f:\dd\ndp\clr\src\BCL\system\runtime\serialization\objectmanager.cs:line 941
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) in f:\dd\ndp\clr\src\BCL\system\runtime\serialization\formatters\binary\binaryobjectreader.cs:line 179
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) in f:\dd\ndp\clr\src\BCL\system\runtime\serialization\formatters\binary\binaryformatter.cs:line 199
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) in f:\dd\ndp\clr\src\BCL\system\runtime\serialization\formatters\binary\binaryformatter.cs:line 113
at Biesse.PlantConfigurator.Core.Misc.DeserializeFromByteArrayT in C:\SeedXP\Interfacce-GITBranch\Sviluppo\Componenti\Biesse.PlantConfigurator.Core\Misc.cs:line 1137
at Biesse.PlantConfigurator.Core.Misc.DeserializeFromByteArrayT in C:\SeedXP\Interfacce-GITBranch\Sviluppo\Componenti\Biesse.PlantConfigurator.Core\Misc.cs:line 1112
at Biesse.PlantConf.Plugin.ToolingRegistry.Plugin.Read(IDataOwner owner, Boolean isDiff) in C:\SeedXP\Interfacce-GITBranch\Sviluppo\PlantConfPlugins\Biesse.PlantConf.Plugin.ToolingRegistry\Plugin.Persistence.cs:line 58
I'm sure that the member '<Initialize>b__29_0' is
IsReadOnly = () => this.IsReadOnly
I used the ISerializationSurrogate to solve the issue
public static T DeserializeFromByteArray<T>(byte[] bytes, SerializationBinder serializationBinder)
{
using (MemoryStream ms = new MemoryStream(bytes))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Binder = serializationBinder;
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(ToolParameterEdit), new StreamingContext (StreamingContextStates.All),
new ToolParameterEditSerializationSurrogate ());
formatter.SurrogateSelector = surrogateSelector;
return (T)formatter.Deserialize(ms);
}
}
However the surrogate to ToolParameterEdit not resolve the problem.
Any idea?
Thanks