BinaryFormatter 反序列化给出 SerializationException
我得到一个:
System.Runtime.Serialization.SerializationException:无法找到 程序集'myNameSpace,版本= 1.0.0.0,文化=中性, PublicKeyToken=null
当尝试在另一个程序中反序列化某些数据而不是我序列化它的程序时。
经过一番谷歌搜索后,我发现显然这只能使用共享程序集来完成。
但是,我的数据库充满了这些序列化对象,我需要一个实用程序来将它们取出。有没有办法覆盖这种行为,只给它提供完全相同的类并强制它反序列化?
我已经找到了这个片段,但我不明白应该如何以及在哪里放置/使用它。
static constructor() {
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
Assembly ayResult = null;
string sShortAssemblyName = args.Name.Split(',')[0];
Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly ayAssembly in ayAssemblies) {
if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0]) {
ayResult = ayAssembly;
break;
}
}
return ayResult;
}
I'm getting an:
System.Runtime.Serialization.SerializationException: Unable to find
assembly 'myNameSpace, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null
When trying to deserialize some data in another program than the program I serialized it with.
After some googling I've found out that apparently this can only be done using a shared assembly.
However, my database is full with this serialized objects, and I need a utility program to get them out. Is there a way to override this behavior and just feed it the exact same class and force it do deserialize?
I already found this snippet, but I don't understand how and where I should put/use this.
static constructor() {
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
Assembly ayResult = null;
string sShortAssemblyName = args.Name.Split(',')[0];
Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly ayAssembly in ayAssemblies) {
if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0]) {
ayResult = ayAssembly;
break;
}
}
return ayResult;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您知道该对象,则无需 DLL 即可解决此问题...
http://spazzarama.com/2009/06/25/binary-deserialize-unable-to-find- assembly/
http://msdn.microsoft.com/en-us/library/system.runtime.serialization。序列化binder(VS.71).aspx
下面是一个示例,它将允许在当前程序集中找到类型,无论最初创建序列化流的程序集版本如何:
You can get around this issue without needing the DLL if you know the object...
http://spazzarama.com/2009/06/25/binary-deserialize-unable-to-find-assembly/
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder(VS.71).aspx
Here is a sample that will allow the types to be found in the current assembly regardless of which version of the assembly originally created the serialized stream:
您需要以某种方式提供对原始类型的引用,以便实用程序知道如何反序列化它。
最简单的方法就是添加最初定义类型的 DLL 作为对实用程序项目的引用。
您发布的代码允许您在解串器确定找不到类型时动态加载相同的 DLL。这是一种更困难的方法(但并不那么困难),但在这两种情况下,您都需要一个定义类型的 DLL...因此可能最简单的方法是通过添加引用来静态链接。
如果您的类型当前不在 DLL 中(例如,如果它们在 EXE 中),我建议您将这些类从 EXE 中提取到新的 DLL 中,并从原始项目和 util 项目引用该 DLL。
You will need to provide a reference to the original type somehow so that the utility program knows how to deserialize it.
The easy way is just to add the DLL the types were originally defined in as a reference to the utility project.
The code you posted allows you to dynamically load that same DLL when the deserializer determines it can't find the type. This is a more difficult approach (but not that difficult), but in both cases you will need a DLL that defines the types... so probably easiest just to statically link by adding the reference.
If your types are not currently in a DLL (e.g. if they are in an EXE), I suggest you pull the classes out of the EXE into a new DLL, and reference that DLL both from the original project and from the util project.
我遇到了类似的问题,并在以下链接的帮助下解决了问题:
BinaryFormatter反序列化-not-finding-a-type
基本上,您需要做的是在反序列化之前订阅 AssemblyResolve 事件。然后反序列化后取消订阅。
这里是我用来解析Assembly的方法:
I ran into a similar problem and I got it working with help of the following link:
BinaryFormatterDeserialize-not-finding-a-type
Basically what you need to do is subscribe to the AssemblyResolve event BEFORE deserializing. Then unsubscribe after deserialization..
Here the method I used to resolve the Assembly:
JTtheGeek 的答案是正确的,自定义
SerializationBinder
是处理此问题的方法。不过,该答案中给出的示例代码不足以满足我的用例。我需要的东西可以:这就是我想出的:
JTtheGeek's answer is correct that a custom
SerializationBinder
is the way to handle this problem. The example code given in that answer isn't sufficient for my use case, though. I needed something that could:This is what I came up with:
如果您无权访问序列化数据的原始程序集,则可以使用 SerializationBinder 或 SerializationSurrogate。这两个接口允许您控制反序列化时类型之间如何转换。
If you don't have access to the original assembly that serialized the data, then you can use a SerializationBinder or a SerializationSurrogate. These two interfaces allow you to control how types are converted between one another when deserializing.
我遵循了 JTtheGeek 回答的解决方案,为了让它为我工作,我必须在语句
assemblyName = currentAssembly; 之前添加以下内容:
之后效果很好!
I followed the solution answered by JTtheGeek and in order to get it work for me I had to add the following just before the statement
assemblyName = currentAssembly;
:After that it worked great!