• .Net 序列化问题 之[未找到反序列化“XXX”类型对象的构造函数]


     序列化在开发的过程中重要性不言而喻。使用场景一般为:

    1、应用程序的状态(对象图)保存到文件系统或数据库中。可在需要的时候对这些对象进行恢复。如ASP.NET通过序列化和反序列化来保存和恢复会话状态。

    2、对象的备份。案件对某些对象的生成极为困难,如需要大量的计算、IO等,但是结果比较恒定,我们可以把这些对象保存下来。

    3、程序可视化对象的复制与粘贴。如WinForm和WPF的对象的复制和粘贴。

    4、网络间对象通信,进程间通信等。

    5、对象的加密和解密。

      一般来说如果继承基类需要基类本身可序列化,如作为万物的Object就是可序列化的。对于不序列化的对象我们可以通过"重写程序集和/或类型"来使不可序列化的对象变得可序列化。

         

         序列化常识

    1、格式化器参考对每个对象的类型进行描述元数据,从而了解如何序列化完整的对象图
    2、格式化器针对循环引用会智能判断从而只生成一次
    3、序列化和反序列化使用反射来获取对象的信息和为对象赋值。
    4、多个对象可序列化到一个流中(类型的全名和类型的定义程序集名称会被写入流)
    5、格式化器使用Assembly.Load来将需要反序列化对象的程序集加载到AppDomain中
    6、格式化器的工作过程
    System.Runtime.Serialization.FormatterServices来序列化类型实例
    序列化过程:
    step1:public static MemberInfo[] GetSerializableMembers(Type type,StreamingContext context);
    step2:public static Object[] GetObjectData(Object obj,MemberInfo[] members);
    step3:格式化器将应用程序集标识和类型的完整名称写入流中
    step4:格式化器遍历两个数组中的元素,将每个成员的名称和值写入流中。
    反序列化过程:
    step1:根据程序集标识和类型的完整名称来获取对象的类型信息,如没有会使用Assembly.Load进行加载
    public static Type GetTypeFromAssembly(Assembly assem,String name);
    step2:为对象分配内存,并不为对象调用构造器。对象的所有字段都被初始化null或0
    public static Object GetUninitializedObject(Type type);
    step3:获取需要反序列化的数组
    public static MemberInfo[] GetSerializableMembers(Type type,StreamingContext context);
    step4:格式化器需要流中的数据创建一个Object对象数组
    step5:为对象分配值
    pubilc static Objevt PopulateObjectMembers(Object obj,Memberinfo[] members,Object[] data);
    7、

    建议:
    1、格式化器出于性能考虑不会验证对象图中所有的对象都能序列化,所以可以会出现流中会有部分已经序列化的对象。
    所以最好先把对象序列化到MemoryStream,成功之后再写入目标流(文件、网络中)
    2、枚举和委托总是可序列化的

    控制序列化和反序列化:
    1、实现了ISerializable接口,格式化器会忽略所有定制attribute,改为构造一个新的System.Runtime.SerializationInfo对象。
    可以通过ISerializable的GetObjectData来自定义序列化的方法。
    特殊的反序列化构造器(这是ISeriablizable需要的)否则会报上述错误(如标题所示的错误)
    [SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]
    protected 类名(SerializationInfo info,StreamContext context)
    {}

      

       

     后记:本来想记录一下这个问题产生的原因,后来确写成了读书笔记。(参见CLR via C# 第三版)

  • 相关阅读:
    mysql修改数据库的存储引擎(InnoDB)
    如何查看进程/服务是否启动
    Spark Streaming 入门
    Graphlab create的基本使用
    构建房屋预测回归模型
    构建应用深层特征的图像检索系统
    构建商品评价的分类器
    Elastic Static初识(01)
    《Linux就该这么学》笔记(二)
    《Linux就该这么学》笔记(一)
  • 原文地址:https://www.cnblogs.com/wangn/p/3559997.html
Copyright © 2020-2023  润新知