无法找到程序集异常,执行反序列化时 [英] Unable to find assembly exception,when perform deserialization

查看:28
本文介绍了无法找到程序集异常,执行反序列化时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 winforms 应用程序有一个自定义控件,其属性LayoutStream"之一是 byte[] 类型并且它是可序列化的属性.目前我已将我的应用程序从 4.6 框架移植到 NetCore 3.0 项目.

在运行移植的 NetCore 3.0 项目时,我在反序列化 resx 文件中的数据时遇到异常.

this.control1.LayoutStream = ((SerializableByteList)(resources.GetObject("control1.LayoutStream")));公共 SerializableByteList LayoutStream{得到{返回布局流;}放{LayoutStream= 值;如果(值!= null)this.stmLayout.Write(value.Bytes.ToArray(), 0, value.Bytes.ToArray().Length);}}[可序列化]公共类 SerializableByteList{公共 SerializableByteList(){字节数 = 新列表<字节>();}公共列表<字节>字节 { 得到;放;}}

<块引用>

发生异常:抛出异常:System.Runtime.Serialization.Formatters.dll 中的System.Runtime.Serialization.SerializationException"System.Runtime.Serialization.Formatters.dll 中发生类型为System.Runtime.Serialization.SerializationException"的未处理异常无法找到程序集 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

请提出解决此问题的解决方案.

解决方案

从根本上说,BinaryFormatter 不可移植;它被设计用于在运行相同代码的两个节点之间进行远程处理,而不是在框架之间持久化数据.所以:我的主要建议很简单:

<块引用>

不要使用BinaryFormatter.曾经.

我意识到这艘船可能已经航行,但一个非常务实的选择是:

  • 选择一个新的序列化器——确保它是可移植的(json、xml、protobuf 等);几乎除了BinaryFormatter
  • 之外的任何东西
  • 在旧代码中,使用当前代码反序列化数据,并使用新选择的序列化器单独序列化
  • 在您的新代码中,仅将其反序列化为新格式
<小时>

push 时,您可以尝试使用自定义 SerializationBinder;这里的想法是你将 SerializationBinder 子类化,覆盖方法,并告诉它在哪里可以找到东西.这里的基本问题是:

  1. 程序集(mscorlib 等)已更改身份
  2. 类型在许多情况下程序集之间移动

这两个问题都需要处理.

部分代码:

var bf = new BinaryFormatter { Binder = MyBinder.Instance };//等等

class MyBinder : SerializationBinder{私人 MyBinder() { }公共静态 MyBinder 实例 { 获取;} = new MyBinder();公共覆盖类型 BindToType(string assemblyName, string typeName){//TODO: 根据已知列表检查 assemblyName 和 typeName,然后//返回应该使用的类型,通常*而不是*//一个它预期的;}公共覆盖 void BindToName(Type serializedType,out string assemblyName, out string typeName){//TODO:相反}}

<小时>

但这是一项艰苦的工作,而且荒谬脆弱.您的时间将更好地用于移植到不同的序列化程序 IMO.很高兴根据您的需要推荐一些.

<小时>

旁注:他们已经反复尝试杀死 .NET Core 的 BinaryFormatter,但遗憾的是它幸存了下来.

My winforms application has a custom control, one of its property "LayoutStream" is byte[] type and it is serializable property. Currently I have ported my application from 4.6 framework to NetCore 3.0 project.

While run ported NetCore 3.0 project, im getting below exception when deserialize the data from resx file.

this.control1.LayoutStream = ((SerializableByteList)(resources.GetObject("control1.LayoutStream")));


    public SerializableByteList LayoutStream
    {
        get
        {
            return LayoutStream;
        }
        set
        {
            LayoutStream= value;
            if (value != null)
                this.stmLayout.Write(value.Bytes.ToArray(), 0, value.Bytes.ToArray().Length);
        }
    }

    [Serializable]
    public class SerializableByteList 
    {
        public SerializableByteList()
        {
            Bytes = new List<byte>();
        }
        public List<byte> Bytes { get; set; }
    }

Exception Occurs: Exception thrown: 'System.Runtime.Serialization.SerializationException' in System.Runtime.Serialization.Formatters.dll An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.Formatters.dll Unable to find assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

Please suggest solution to resolve this.

解决方案

Fundamentally, BinaryFormatter is not portable; it was designed for remoting between two nodes running identical code, not persisting data between frameworks. So: my main advice is simply:

Don't use BinaryFormatter. Ever.

I realise this boat may have sailed, but a very pragmatic option is to:

  • pick a new serializer - making sure it is portable (json, xml, protobuf, etc); just about anything except BinaryFormatter
  • in your old code, deserialize the data with your current code, and serialize it separately with the new choice of serializer
  • in your new code, deserialize it in the new format only

At a push, however, you could try playing with a custom SerializationBinder; the idea here is that you subclass SerializationBinder, override the methods, and tell it where to find things. The fundamental problem here is that:

  1. the assemblies (mscorlib etc) have changed identity
  2. types have moved between assemblies in many cases

Both of those problems need handling.

Partial code:

var bf = new BinaryFormatter { Binder = MyBinder.Instance };
// etc

with

class MyBinder : SerializationBinder
{
    private MyBinder() { }
    public static MyBinder Instance { get; } = new MyBinder();
    public override Type BindToType(string assemblyName, string typeName)
    {
        // TODO: check assemblyName and typeName against some known list, and
        // return the Type that should be used, often *instead of* the
        // one it expected;
    }
    public override void BindToName(Type serializedType,
        out string assemblyName, out string typeName)
    {
        //TODO: the opposite
    }
}


But this is hard work, and absurdly brittle. Your time would be much better spent porting to a different serializer, IMO. Happy to recommend some, depending on your needs.


Side note: they have tried repeatedly to kill BinaryFormatter for .NET Core, but it sadly survived.

这篇关于无法找到程序集异常,执行反序列化时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆