Dear Stack Overflow community, I thought I'd never have to ask this question, but apparently something is going wrong with serialization or my usage of it.
I have a class which I need to serialize:
[Serializable]
public class Device : ISerializable, IDisposable
{
public delegate void ListChangedEventHandler(object sender, ListChangedEventArgs e);
public string Name { get; set; }
public string Description { get; set; }
public string IPAddress { get; set; }
[Browsable(false)]
public ThreadSafeBindingList<Item> Items { get; set; }
[Browsable(false)]
public MibEntity AssociatedMibEntity { get; set; }
//methods etc.
}
A little explanation:
ThreadSafeBindingList is inherited from System.ComponentModel.BindingList MibEntity is a class of SharpSNMP library (https://sharpsnmp.com/)
Problem: When I try to deserialize the object, MibEntity is always null. Other properties are fine. MibEntity class is in external dll, which I reference in the project where Device class resides.
This is its content:
[Serializable]
public class MibEntity
{
public MibEntity()
{
Children = new List<MibEntity>();
}
[Browsable(false)]
public List<MibEntity> Children { get; set; }
[Browsable(true)]
[Category("General")]
public string OID { get; set; }
private string _name;
[Browsable(true)]
[Category("General")]
public string Name
{
get { return _name; }
set { _name = value; }
}
[Browsable(true)]
public string Description { get; set; }
[Browsable(false)]
public int Value { get; set; }
[Browsable(true)]
public AccessType AccessType { get; set; } //this is enum from SharpSNMP library
[Browsable(true)]
public Status Status { get; set; } //this is enum from same assembly as this class
[Browsable(true)]
public string Syntax { get; set; }
[Browsable(true)]
public bool IsTableEntry { get; set; }
[Browsable(true)]
public IDefinition IDefinition { get; set; } //this is interface from SharpSNMP library
}
I use BinaryFormatter for serialization and deserialization. Thank you for your help!
This invariably means you have made an error in your custom ISerializable
implementation; the following works fine:
protected Device(SerializationInfo info, StreamingContext context)
{
Name = info.GetString("Name");
//...
AssociatedMibEntity = (MibEntity)info.GetValue(
"AssociatedMibEntity", typeof(MibEntity));
}
void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", Name);
//...
info.AddValue("AssociatedMibEntity", AssociatedMibEntity);
}
with validation:
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter();
bf.Serialize(ms, new Device {
AssociatedMibEntity = new MibEntity { Name = "Foo"}});
ms.Position = 0;
var clone = (Device)bf.Deserialize(ms);
Console.WriteLine(clone.AssociatedMibEntity.Name); // Foo
}
However, unless there is a good reason to implement ISerializable
, you might be better served by simply removing your ISerializable
implementation completely - noting that this will be a breaking change (any existing data won't deserialize correctly if you do this).
[Serializable]
public class Device : IDisposable // <=== no ISerializable; also removed
// GetObjectData and custom .ctor
Also: my usual rant: BinaryFormatter
might not be your best bet if you are storing this data anywhere. It is... brittle. There are a range of far more reliable serializers.