解决反序列化(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));

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

时间: 2024-10-07 11:57:34

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

在反序列化类时提示无法找到程序集

在反序列化类的时候,弹出提示,无法找到程序集MapInfo,但是在项目中,明明通过引用添加了该程序集,并且放在了根目录下面,具体的反序列化的代码如下: public object Deserialize(byte[] data,int offset,int length) { BinaryFormatter formatter = new BinaryFormatter(); MemoryStream rems = new MemoryStream(data,offset,length); da

warning MSB3245: 未能解析此引用。未能找到程序集“CemeteryBLL”。请检查磁盘上是否存在该程序集。 如果您的代码需要此引用,则可能出现编译错误。

多层架构,在每次重新生成解决方案的时候,老是提示:warning MSB3245: 未能解析此引用.未能找到程序集"CemeteryBLL".请检查磁盘上是否存在该程序集. 如果您的代码需要此引用,则可能出现编译错误. 但是如果逐个生成,那就没问题.这是因为在多层架构中,项目之间有引用关系,比如三层架构,UI界面层引用了BLL业务层,BLL业务层引用了DAL数据层,如果我们全部生成解决方案,它生成的顺序如果不是先从DAL再BLL最后UI层,则会提示上面那个错误.因为如果先生成UI层,那

解决gremlin-dirver访问tinkerpop服务器提示序列化错误

解决gremlin-dirver访问tinkerpop服务器提示序列化错误 问题描述 程序集成了gremlin-driver,访问远程tinkerpop服务器,在执行创建节点操作时,返回如下错误栈: 2017-08-17 15:25:27.519 ERROR 13548 --- [n-driver-loop-3] o.a.t.g.d.Handler$GremlinResponseHandler : Could not process the response io.netty.handler.c

如何解决duplicate symbols for architecture x86_64编译错误

ld: 5 duplicate symbols (这里出现的属性就是问题出现的关键)_count for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) /Users/zxtw/Library/Developer/Xcode/DerivedData/FightLandlord-gfkaxalabyaagtcimlrskdbtudbx/Build/

解决java代码测试http协议505错误

代码功能:通过java代码获取网页源代码: 所用工具:Myclipse8.5+tomcat6.0+浏览器 系统环境:windows xp旗舰版火狐浏览器版本: IE浏览器版本: 测试http协议有错误java代码如下. import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.

命名空间 system.windows 中不存在类型或命名空间名称 forms (是否缺少程序集引用 )错误

C#项目: 添加“using System.Windows.Forms;”之后提示“命名空间 system.windows 中不存在类型或命名空间名称 forms (是否缺少程序集引用 )”错误, 查询知缺少System.Windows.Forms程序集,在VS2015中添加次程序集,步骤为: 项目>添加引用 在图中右上角搜索框中搜索“System.Windows.Forms”,出现如下选项: 勾选“System.Windows.Forms”项,确定,即可.

解决 UnicodeDecodeError: 'ascii' codec can't decode 错误

Ctrl + B 没结果. 查看控制台信息 如下: Running python -u -i C:\2.pyTraceback (most recent call last):  File ".\sublime_plugin.py", line 337, in run_  File ".\exec.py", line 154, in run  File ".\exec.py", line 45, in __init__UnicodeDecodeE

addEventListener attachEvent和解决IE 6 7 8 this指向错误

[JS] addEventListener attachEvent和解决IE 6 7 8 this指向错误   电梯直达 1#  php 发表于 2014/4/13 01:17 | 只看该作者  标准浏览器中可以使用addEventListener()函数来给DOM元素绑定事件,使用removeEventListener()函数移除事件绑定,而IE6 IE7 IE8不支持addEventListener()和removeEventListener(),只能使用attachEvent()和deta

有效解决Win10用鲁大师ultra dma crc错误计数的恢复发方法

我们在win10系统电脑的使用中,鲁大师是很多小伙伴都在用的扫描的软件,我们可以直接使用来恢复我们的电脑,今天看到有小伙伴在使用的时候出现Win10用鲁大师ultra dma crc错误计数,这个问题怎么恢复呢,今天小编就来跟大家分享一下有效解决Win10用鲁大师ultra dma crc错误计数的恢复发方法. 具体的方法和详细的步骤如下: 原因分析 出现该情况有可能硬盘与主板接触不良,软件误报,或者硬盘质量问题等等. 解决方法: 1.把USB外界排查拔掉,换上一条质量好的SATA数据线,查看问