BinaryFormatter Custom Binder Alternative Using Newtonsoft.Json.JsonSerializer In C#
Hello Everyone!
Cheers!
In relation to the previous post on updating the serialization and deserialization using BinaryFormatter class to NewtonSoft's JsonSerializer, we also need to change the Binder functionality using NewtonSoft. The class below inherits the SerializationBinder and overrides the BindToType() function.
sealed class HELPERSCustomBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { if (!typeName.ToUpper().Contains("SYSTEM.STRING")) { throw new SerializationException("Only List<string> is allowed"); } return Assembly.Load(assemblyName).GetType(typeName); } }
The class above will then be assigned to the Binder property of BinaryFormatter as shown from the code snippet below.
public static T BuildFromSerializedBuffer<T>(byte[] buffer) where T : new() { MemoryStream MS; BinaryFormatter BF; T rtn; rtn = default(T); try { using (MS = new MemoryStream(buffer)) { BF = new BinaryFormatter(); BF.Binder = new HELPERSCustomBinder(); rtn = (T)BF.Deserialize(MS); } } catch { //TODO } return rtn; }
After searching the NewtonSoft's documentation, I did found out the equivalent functionality that is to implement the ISerializationBinder interface and it's BindToType() method similar to the class above using the SerializationBinder.
sealed class HELPERSCustomBinder : ISerializationBinder { public IList<Type> KnownTypes { get; set; } public Type BindToType(string assemblyName, string typeName) { return KnownTypes.SingleOrDefault(t => t.Name == typeName); } public void BindToName(Type serializedType, out string assemblyName, out string typeName) { assemblyName = null; typeName = serializedType.Name; } }
To set the SerializationBinder property of the serializer object, you need to set first the KnownTypes property of the Custom Binder with data types or complex objects. Then assign the known types binder object to the SerializationBinder property of the serializer object. That's it.
public static T BuildFromSerializedBuffer<T>(byte[] buffer) where T : new() { MemoryStream MS; T rtn; rtn = default(T); try { using (MS = new MemoryStream(buffer)) { var knownTypesBinder = new HELPERSCustomBinder() { KnownTypes = new List<Type> { typeof(string) } }; var serializer = new Newtonsoft.Json.JsonSerializer(); serializer.SerializationBinder = knownTypesBinder; using (var sr = new StreamReader(MS)) { using (var jsonTextReader = new JsonTextReader(sr)) { rtn = serializer.Deserialize<T>(jsonTextReader); } } } } catch { //TODO } return rtn; }
Cheers!
Comments
Post a Comment