Обновление объекта данных с использованием SerializationBinder и Surrogate
Я получаю объект типа "Project1.Class1[]", который нельзя преобразовать в тип "Project2.Class1[]". при попытке перенести данные из проекта 1 класса 1 в проект 2
Передаваемый объект - это список Project1.Class1, который содержит подобъект Class2. Итак, я создал два суррогатных класса для обработки преобразования объектов, но я получаю эту ошибку до того, как суррогаты обрабатывают обновление списка Class1.
[Serializable]
internal class Class1Upgrader
{
public BinaryFormatter CreateFormatter()
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
SurrogateSelector selector = new SurrogateSelector();
selector.AddSurrogate(typeof(Project1.Class1), new StreamingContext(StreamingContextStates.All), new Class1Surrogate());
selector.AddSurrogate(typeof(Project1.Class2), new StreamingContext(StreamingContextStates.All), new Class2Surrogate());
binaryFormatter.SurrogateSelector = selector;
binaryFormatter.Binder = new Class1Binder();
return binaryFormatter;
}
}
[Serializable]
internal class Class1Binder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName == typeof(List<Project1.Class1>).FullName)
{
return typeof(List<Project2.Class1>);
}
return null;
}
}
Изменить: после исправления проблемы это решение станет огромным подспорьем для людей, которым необходимо обновить поля varbinary в SQL в C#. Большинство корней кода лежат в основе того, чтобы люди начали.:)
1 ответ
[Serializable]
internal class Class1Upgrader
{
public BinaryFormatter CreateFormatter()
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
SurrogateSelector selector = new SurrogateSelector();
selector.AddSurrogate(typeof(Project2.Class1), new StreamingContext(StreamingContextStates.All), new Class1Surrogate());
selector.AddSurrogate(typeof(Project1.Class2), new StreamingContext(StreamingContextStates.All), new Class2Surrogate());
binaryFormatter.SurrogateSelector = selector;
binaryFormatter.Binder = new Class1Binder();
return binaryFormatter;
}
}
[Serializable]
internal class Class1Binder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName.Contains("System.Collections.Generic.List`1[[Project1.Class1, Class1"))
{
return typeof(List<Project2.Class1>);
}
if (typeName == typeof(Project1.Class1).FullName)
{
return typeof(Project2.Class1);
}
return null;
}
}
internal class Class1Surrogate : ISerializationSurrogate
{
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
Project2.Class1 result = (Project2.Class1)obj;
//Handle the logic here to convert your old properties into your new one
return result;
}
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
}
internal class Class2Surrogate : ISerializationSurrogate
{
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
Project2.Class1 result = new Project2.Class1();
//Handle the logic here to convert your old properties into your new one
return result;
}
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
}
Итак, решение состоит в том, чтобы изменить привязку, чтобы вернуть новый объект, а не старый, который будет передан через суррогат. Это важно при работе со списком объекта, который вы пытаетесь обновить. Итак, добавив typeof(Project2.Class1), суррогатный класс обработает преобразование ваших свойств. Таким образом, в вашем SetObjectData в суррогате в объекте будет typeof(Project2.Class1), как показано выше в Class1Surrogate.