【发布时间】:2015-04-18 05:27:38
【问题描述】:
这是一个让我花了一整天时间的问题。我想我会发布解决方案,以防其他人点击它。
我有一个调用 ASMX Web 服务的 .NET Office 插件。它获得了有效的 XML 响应,但 XmlSerializationReader 无法正确反序列化响应。它找不到我的一个 DLL,并引发 FileNotFoundException。
基本结构是这样的:
Utility Assembly -- 包含一些 DTO 所依赖的常用实用程序类。
namespace MyCompany.CommonUtilities
{
[Serializable]
public class UtilityClass
{
// Various fields and properties..
}
}
DTO 组装 -- 包含用于 Web 服务调用的可序列化对象
using MyCompany.CommonUtilities;
namespace MyCompany.DtoObjects
{
[Serializable]
public class WebResponseDto
{
// Various other fields and properties..
public UtilityClass Property1 { get; set; }
}
}
这一切都在 .NET 3.5 下运行良好,现在仍然如此。如果我运行针对 3.5 构建的旧插件,一切正常。
发生的事情是,在 .NET 4.5 中,它们完全重新设计了 Xml 序列化程序在运行时生成的方式。请参阅https://stackoverflow.com/a/14699617/3183464 和 .NET 4.5 的自述文件。最终结果是 Xml Serializer 无法为我的 Utilities 项目找到正确的 DLL。
当我编译到 .NET 4.5 时,Web 服务返回一个正确序列化的对象,但它不能在客户端反序列化。相反,我只是得到
Exception: There is an error in XML document (1, 997).
System.IO.FileNotFoundException: Could not load file or assembly 'MyCompany.CommonUtilities, Version=6.0.0.23028, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMyCompanyService.Read101_WebResponseDto(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMyCompanyService.Read258_WebMethodResponse()
at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer285.Deserialize(XmlSerializationReader reader)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
这很令人困惑,因为 Utilities DLL 在调用 Web 服务之前就已经加载了。
查看 Fusion 日志,我看到实用程序程序集的两个不同的加载事件。第一次是我的 Visio 插件第一次加载时,因为它依赖于实用程序类:
LOG: DisplayName = MyCompany.CommonUtilities, Version=6.0.0.23028, Culture=neutral, PublicKeyToken=null (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Office/Office14/
Calling assembly : MyCompany.VisioAddIn, Version=6.0.0.23028, Culture=neutral, PublicKeyToken=null.
LOG: This bind starts in LoadFrom load context.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities/MyCompany.CommonUtilities.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities/MyCompany.CommonUtilities.EXE.
LOG: Attempting download of new URL file:///C:/Users/MyUser/Documents/DevProjects/VisioAddIn/bin/Debug/MyCompany.CommonUtilities.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Users\MyUser\Documents\DevProjects\VisioAddIn\bin\Debug\MyCompany.CommonUtilities.dll
注意上下文:它调用Assembly.LoadFrom(),并找到了DLL。
但后来,在运行时生成的序列化程序集尝试加载相同的程序集以反序列化 DTO,但找不到它:
LOG: DisplayName = MyCompany.CommonUtilities, Version=6.0.0.23028, Culture=neutral, PublicKeyToken=null (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Office/Office14/
Calling assembly : (Unknown).
LOG: This bind starts in default load context.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities/MyCompany.CommonUtilities.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Office/Office14/MyCompany.CommonUtilities/MyCompany.CommonUtilities.EXE.
LOG: All probing URLs attempted and failed
看看发生了什么?
运行时生成的程序集没有意识到它需要查看我的插件所在的文件夹。它只是调用Assembly.Load(),它使用默认的加载上下文。
由于它是作为 Visio.EXE 的一部分运行的,Fusion 会搜索明显的位置:C:\Program Files (x86)\Office,但没有找到任何东西。结果:找不到文件。
【问题讨论】:
标签: c# .net plugins xml-serialization