c# - 使用 SerializationBinder 和 Surrogate 更新数据对象
问题描述
我得到一个“Project1.Class1[]”类型的对象无法转换为“Project2.Class1[]”类型。尝试将数据从 class1 项目 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;
}
}
编辑:修复问题后,此解决方案将对需要在 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();
}
}
因此,解决方案是更改您的活页夹以返回新对象,而不是通过代理传递的旧对象。在使用您尝试升级的对象列表时,这一点很重要。因此,添加 typeof(Project2.Class1) 代理类将处理转换您的属性。因此,在您的 SetObjectData 中,对象中的代理项将是 typeof(Project2.Class1),如上面 Class1Surrogate 中所示。
推荐阅读
- php - 为什么具有 distinct 和 group by 的查询不返回结果?
- python - 获取所有匹配项,包括重叠
- add-in - 使用C#在VISO中格式化文本内的形状
- windows - 如何使用 gnuwin32 Makefile 执行 powershell/cmd 命令?
- graph - 图分区后建立新的邻接矩阵
- angular - 如何使用 Angular 过滤表中的行?
- android - RecyclerviewAdapter代码在android中不起作用
- java - 无法使用 Intent.ACTION_VIEW 在 Android 上打开 excel 文件
- node.js - 拆分 Goole-Play-Scraper 结果
- logging - 在 boto3 中更改 urllib3 的日志记录级别