解决反序列化(Deserialize)无法找到程序集的错误

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));

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

posted @   LuoCore  阅读(1094)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示