尝试使用NetDataContractSerializer反序列化类型时,我收到了FileLoadException:
给定的程序集名称或代码库无效。 (来自HRESULT的异常:0x80131047)
此错误与序列化程序无关;尝试在运行时通过Assembly Qualified Name加载类型会导致同样的失败。
我已经在AssemblyResolve event附加了一位听众,看看发生了什么:
ResolveEventHandler reh = (o, e) =>
{
var tryGet = AppDomain.CurrentDomain.GetAssemblies()
.Where(x => x.FullName == e.Name).FirstOrDefault();
if (tryGet != null)
return tryGet;
//EDIT: Crap, the following line is a stupid bug STUPID! Ignore!
return Type.GetType(e.Name).Assembly;
};
using (var stream = System.IO.File.OpenRead(serializedObjectFilename))
{
try
{
AppDomain.CurrentDomain.AssemblyResolve += reh;
var ser = new NetDataContractSerializer();
return ser.Deserialize(stream) as MyType;
}
finally
{
AppDomain.CurrentDomain.AssemblyResolve -= reh;
}
}
通过处理程序调试可以看出名义上的“奇怪行为”。虽然tryGet
永远不是null
(在这种情况下,所需的程序集始终加载到AppDomain中),但操作总是会失败(如果留给自己)。 换句话说,调用 编辑:我将程序集的强名称与程序集限定名称混为一谈类型;请忽略那个错误。具有讽刺意味的是,它没有引发不同的错误,所以在提出这个问题之前我没有抓住这个。Type.GetType(e.Name).Assembly
会导致抛出FileLoadException。
另一部分信息:Assembly.Load(e.Name)
始终返回有效的程序集。我不确定为什么这样可行,而反序列化过程中幕后使用的方法失败。
Fusion Log报告加载程序正在尝试加载正确的程序集,但由于在可执行文件的专用路径中找不到程序集,因此失败。
为什么在AppDomain中已加载程序集时尝试加载程序集?
有关融合记录的更多细节......
我在方法调用之前和期间捕获了导致异常抛出的所有程序集加载。以下是相关日志,按创建顺序:
AFAICT,Visual Studio将程序集加载到解决方案的AppDomain中(ffs我希望Fusion Log捕获尝试加载的AppDomain;它毕竟记录了调用程序集)。
在此之后,我进行了反序列化调用。结果是Fusion中的单个日志:
绑定结果:hr = 0x80070002。系统找不到指定的文件。
同样,Fusion正试图通过其强名称从可执行文件的应用程序库加载。一件好事;它试图从GAC加载,因此一旦部署,我可能没有相同的问题。但是我仍然不知道为什么程序集不能位于appdomain中。
更有趣的东西......
这会引发对反序列化的调用:
MyType test = new MyType ();
var serialized = Serializer.ToXml(test);
// the following line fails with a FileLoadException
var deserialized = Serializer.FromXml<MyType>(serialized);
其中ToXml和FromXml都使用NetDataContractSerializer和Write / ReadObject。程序集的早期执行是从程序包的安装目录加载的,但由于某种原因,NDCS不希望使用AppDomain中的程序集。此测试表明它不是版本控制的问题。
答案 0 :(得分:0)
我在代码中发现奇怪的一件事就是:
GetAssemblies().Where(x => x.FullName == e.Name)
e
用作程序集的名称,因为它匹配Assembly.Name
,因此不会有类/类型的名称,然后在这里:
return Type.GetType(e.Name).Assembly;
e
用作完全程序集限定的类型名称,我认为它将包含类/类型名称和程序集名称。
这是故意的吗?
修改强>
抱歉,我在您编辑帖子时发布了此回复,并自行抓错了...