Нужна двоичная сериализация без требований установки [Serializable]
Видно 3 варианта:
1) Самодельная реализация.
2) Через Reflector вытащить исходники BinaryFormatter,и связанных с ним классов , удалить код проверки [Serializable], компильнуть и юзать.
3) Заставить работать через SerializationSurrogate. Но что-то не выходит никак, с циклическими ссылками.
В чем может быть проблема, в приведенном коде?
Во время десериализации выскакивает exeption, якобы ID=3 прописано а такого объекта нет.
Кроме того GetObjectData, вызывается второй раз для того же объекта, на циклической ссылке (хотя и не зацикливается бесконечно).
Если не писать объект второй раз, а просто return, то все равно exception.
Странно что если Surrogate подключен при сериализации, а десериализация без сурогата, то нормально десериализуется.
А если сериализация без сурогата, десериализация с сурогатом дает тот же exception.
Значит проблема с десериализацией. Exception вылетает из ObjecManager во время разборок с сылками (Fixup...), еще до того как вызывается SetObjectData из сурогата.
class CommonSerializationSurrogate : ISerializationSurrogate
{
// Method called to serialize object
public void GetObjectData(Object obj,SerializationInfo info, StreamingContext context)
{
BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
foreach (FieldInfo fi in obj.GetType().GetFields(bf))
info.AddValue(fi.Name, fi.GetValue(obj));
}
// Method called to deserialize object
public Object SetObjectData(Object obj,SerializationInfo info, StreamingContext context,ISurrogateSelector selector)
{
BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
foreach (FieldInfo fi in obj.GetType().GetFields(bf))
fi.SetValue(obj, info.GetValue(fi.Name, fi.FieldType));
return obj;
}
}
class CommonSurrogateSelector : ISurrogateSelector
{
public CommonSerializationSurrogate _Surrogate = new CommonSerializationSurrogate();
public void ChainSelector(ISurrogateSelector selector){}
public ISurrogateSelector GetNextSelector(){return null;}
public ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector)
{
selector = this;
return _Surrogate;
}
}
[Serializable]
class Cl1
{
public Cl2 cl2;
}
[Serializable]
class Cl2
{
public Cl1 cl1;
}
И использование:
var cl2 = new Cl2();
cl2.cl1 = new Cl1();
cl2.cl1.cl2 = cl2;
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
CommonSurrogateSelector ss = new CommonSurrogateSelector();
bf.SurrogateSelector = ss;
bf.Serialize(ms, cl2);
ms.Position = 0;
object obj = bf.Deserialize(ms);