使用 SerializationBinder 和 Surrogate 更新数据对象
Data object update using SerializationBinder and Surrogate
我得到一个 'Project1.Class1[]' 类型的对象无法转换为 'Project2.Class1[]' 类型。'当试图将数据从 class1 项目 1 取到项目 2
传递的对象是包含 Class2 子对象的 Project1.Class1 列表。所以我创建了两个 Surrogate 类 来处理对象的转换,但是在代理处理更新 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;
}
}
编辑:解决问题后,此解决方案将对需要在 C# 中更新 SQL 中的 varbinary 字段的人们提供巨大帮助。大多数代码根都在让人们开始的答案中。 :)
[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();
}
}
所以解决方案是将活页夹更改为 return 新对象而不是要通过代理项传递的旧对象。这在使用您尝试升级的对象的列表时很重要。因此,添加 typeof(Project2.Class1) 代理项 class 将处理您的属性转换。因此,在您的 SetObjectData 中,对象中的代理项将是 typeof(Project2.Class1),如上面在 Class1Surrogate 中所示。
我得到一个 'Project1.Class1[]' 类型的对象无法转换为 'Project2.Class1[]' 类型。'当试图将数据从 class1 项目 1 取到项目 2
传递的对象是包含 Class2 子对象的 Project1.Class1 列表。所以我创建了两个 Surrogate 类 来处理对象的转换,但是在代理处理更新 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;
}
}
编辑:解决问题后,此解决方案将对需要在 C# 中更新 SQL 中的 varbinary 字段的人们提供巨大帮助。大多数代码根都在让人们开始的答案中。 :)
[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();
}
}
所以解决方案是将活页夹更改为 return 新对象而不是要通过代理项传递的旧对象。这在使用您尝试升级的对象的列表时很重要。因此,添加 typeof(Project2.Class1) 代理项 class 将处理您的属性转换。因此,在您的 SetObjectData 中,对象中的代理项将是 typeof(Project2.Class1),如上面在 Class1Surrogate 中所示。