【问题标题】:XmlSerializer trying to load unrelated dll in .NETXmlSerializer 试图在 .NET 中加载不相关的 dll
【发布时间】:2023-03-12 17:44:01
【问题描述】:

我有一个类在其方法中使用 Oracle.DataAccess.dll(32 位)中的类。这些方法在服务器(32 位)上调用。所有类的属性都不是属于 Oracle.DataAccess.dll 的类型

在客户端,我们引用了相同的 dll,以下代码在 32 位机器上运行良好,但在 64 位机器上运行良好。

    Type t = typeof(ClassA);
    XmlSerializer s = new XmlSerializer(t);

在 64 位机器上出现以下错误:

System.BadImageFormatException: Could not load file or assembly 'Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. An attempt was made to load a program with an incorrect format.
File name: 'Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342'
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializerContract.CanSerialize(Type type)
   at System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(Type type, String defaultNamespace, XmlSerializerImplementation& contract)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)

为什么 CLR 试图加载 Oracle.DataAccess.dll,尽管该类没有任何属于 dll 的属性?

编辑 当我们传递一个空的 XmlAttributeOverrides 时不会发生异常

XmlAttributeOverrides o = new XmlAttributeOverrides();
XmlSerializer s = new XmlSerializer(t, o);

【问题讨论】:

  • 当您传入XmlAttributeOverrides 时,XML 序列化程序总是从头开始创建一个新的临时程序集,并且不检查缓存或预生成的序列化程序程序集。你会预先生成这些吗?
  • 不,我们不预先生成
  • 其实做不做都无所谓。 new XmlSerializer(t) 和 new XmlSerializer(t, o) 采用稍微不同的代码路径,在后一种情况下,永远不会调用引发您引用的异常的方法。不过,我怀疑生成的序列化程序是否可以工作。
  • 在XmlSerializer的两个构造函数中,区别在于XmlAttributeOverrides参数是空的,所以应该不会对结果输出/xml有任何影响?
  • 不应该。我的意思是当您尝试使用序列化程序时,可能会加载有问题的程序集(并抛出异常)。毕竟,new XmlSerializer(t) 抛出异常是有原因的,即使我的心灵调试能力太弱,无法告诉你原因。另外,需要记住的一点是,每次调用重载时都在编译一个新的临时程序集 XmlAttributeOverrides

标签: .net dll xml-serialization 32bit-64bit odp.net


【解决方案1】:

此错误通常意味着程序集是混合程序集,即它同时包含托管代码和本机代码。所以从操作系统的 POV 来看,它只是一个 32 位的 dll,不能加载到 64 位的进程中。如果 Oracle 提供此程序集的 32 位和 64 位版本,则您必须修改部署过程以确保安装正确的程序集。如果只有 32 位程序集可用,则除了使托管应用程序 x86 而不是 anycpu 之外,您几乎无能为力。如果这不切实际,一种解决方案是创建一个单独的 32 位服务进程来加载此程序集,并让 64 位主进程使用选择的 IPC 机制与其通信。

【讨论】:

  • 传递给 XmlSerializer 的类型没有来自 Oracle dll 的任何属性,为什么还要尝试加载它?
  • 也许它的代码引用了这个程序集(可能间接地,通过另一个程序集)。基类、属性、扩展方法...尝试在程序集解析事件中设置断点并查看堆栈跟踪/本地。
猜你喜欢
  • 2014-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 2015-09-24
相关资源
最近更新 更多