使用serializationbinder和代理项更新数据对象

dphi5xsq  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(363)

我正在获取类型为“project1.class1[]”的对象,在尝试将数据从class1项目1获取到项目2时,该对象无法转换为类型“project2.class1[]”
传递的对象是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字段的人将是一个巨大的帮助。大多数代码根都在答案中,以帮助人们入门。:)

fkaflof6

fkaflof61#

[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),如上面在classsurrogate中所示。

相关问题