博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决反序列化(Deserialize)无法找到程序集的错误
阅读量:5818 次
发布时间:2019-06-18

本文共 2188 字,大约阅读时间需要 7 分钟。

http://blog.csdn.net/w_s_q/article/details/5677536

 

 

在使用.NET序列化对象时,会将程序集信息也包含进去。如果将序列化之后的字节数组通过网络(或其他传输方式)传输到另一个应用程序,再使用Deserialize反序列化还原对象时,可能(注意是可能)会出现无法找到程序集的错误。之所以说是可能,是因为如果两边的应用程序结构(命名空间、类结构、程序名、程序签名、程序版本等)相同,则不会出现该错误。下面说一个具体实例:

在客户端动态生成一条SELECT语句,将该语句发送到服务器执行,再将执行后的结果返回给客户端。(题外话:要实现本功能完全可以不使用序列化和反序列化的方法,本实例只是为了解释如何解决反序列化时出现的无法找到程序集的错误)

解决方案:

创建一个.NET类库,把要传输的对象做成一个结构或类放在类库(假设为ClassLib.dll)中。如:

view plaincopy to clipboardprint?

[Serializable]  
public struct Data  
{  
    public string sql;  
[Serializable]
public struct Data
{
    public string sql;
}

 

然后在客户端程序(假设为Client.exe)中引用ClassLib.dll,创建Data对象,给Data.sql赋值,再调用Serialize方法将Data对象序列化成字节数组发送出去。参考代码:

 view plaincopy to clipboardprint?

BinaryFormatter formatter = new BinaryFormatter();  
MemoryStream mem = new MemoryStream();  
 
ClassLib.Data data;  
data.sql="select * from table";  
formatter.Serialize(mem, data);  
mem.Seek(0, SeekOrigin.Begin);  
byte[] buffer = mem.GetBuffer(); //这里使用mem.GetBuffer()要比mem.ToArray()效率高,  
                                   //因为前者直接返回mem使用的内存,后者是创建一块合适大小的内存,  
                                    //再将mem对象缓存中的数据拷贝进去。  
                                    //但是如果改变使用GetBuffer方法返回的数组中数据的值,  
                                    //则mem对象缓存中的值也会变化  
Send(buffer, mem.Length); //Send原型为 void Send(byte[] buf, long bufLen)  
                          //之所以Send函数要有第2个参数bufLen,  
                             //是因为使用GetBuffer方法返回的缓存中有未使用的字节  
                             //通过给该参数传递mem.Length可以让Send函数只发送使用的字节 
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream mem = new MemoryStream();

ClassLib.Data data;

data.sql="select * from table";
formatter.Serialize(mem, data);
mem.Seek(0, SeekOrigin.Begin);
byte[] buffer = mem.GetBuffer(); //这里使用mem.GetBuffer()要比mem.ToArray()效率高,
                                   //因为前者直接返回mem使用的内存,后者是创建一块合适大小的内存,
                                    //再将mem对象缓存中的数据拷贝进去。
                                    //但是如果改变使用GetBuffer方法返回的数组中数据的值,
                                    //则mem对象缓存中的值也会变化
Send(buffer, mem.Length); //Send原型为 void Send(byte[] buf, long bufLen)
                          //之所以Send函数要有第2个参数bufLen,
                             //是因为使用GetBuffer方法返回的缓存中有未使用的字节
                             //通过给该参数传递mem.Length可以让Send函数只发送使用的字节

在服务器端(假设为Server.exe)中也引用ClassLib.dll,调用Deserialize函数反序列化接收到的字节得到Data对象。参考代码:

view plaincopy to clipboardprint?

ClassLib.Data data = (ClassLib.Data)formatter.Deserialize(new MemoryStream(data, index, length)); 
ClassLib.Data data = (ClassLib.Data)formatter.Deserialize(new MemoryStream(data, index, length));

至此序列化和反序列化完成。今后在库变换时,只要保证服务器和客户端的库一致,就可以了。

转载于:https://www.cnblogs.com/LuoEast/p/7454332.html

你可能感兴趣的文章
CentOS 6.6 FTP install
查看>>
图解Ajax工作原理
查看>>
oracle导入导出小记
查看>>
聊一聊log4j2配置文件log4j2.xml
查看>>
NeHe OpenGL教程 第七课:光照和键盘
查看>>
修改上一篇文章的node.js代码,支持默认页及支持中文
查看>>
Php实现版本比较接口
查看>>
删除设备和驱动器中软件图标
查看>>
第四章 TCP粘包/拆包问题的解决之道---4.1---
查看>>
html语言
查看>>
从源码看集合ArrayList
查看>>
spring-boot支持websocket
查看>>
菜鸟笔记(一) - Java常见的乱码问题
查看>>
我理想中的前端工作流
查看>>
记一次Git异常操作:将多个repository合并到同一repository的同一分支
查看>>
CodeIgniter 3.0 新手捣鼓源码(一) base_url()
查看>>
Chrome 广告屏蔽功能不影响浏览器性能
查看>>
vSphere 6将于2月2日全球同步发表
查看>>
Android状态栏实现沉浸式模式
查看>>
让你的APP实现即时聊天功能
查看>>