我不太明白,但Kev 的指针终于让我进入了工作状态。WCF 客户端包装器为您提供了实际的异常 - 而不是 CommunicationObjectFaultedException,VS2008 代理为您提供了(如何解决这个问题?)。
该异常是 FileLoadException,抱怨 System.ServiceModel:
主机存储中的程序集与 GAC 中的程序集具有不同的签名。(HRESULT 异常:0x80131050)有关详细信息,请参阅 Microsoft 知识库文章 949080。
当然,KB 949080没有任何帮助,因为它仍然指的是 SQL 2005(顺便说一句,我注意到很多 SQL 2008 错误消息,并且仍然指的是 2005 - 你认为他们至少可以替换了错误消息中的文本)并在更新 .NET FX 后处理问题——这并没有发生。
不过,这确实让我想到了 32 位和 64 位的区别。我的 SQL 2008 服务器是 Server 2008 x64 上的 x64 - 因此,它同时具有 C:\Windows\Microsoft.NET\Framework 和 Framework64 文件夹。由于 SQL Server 是一个 64 位进程,并且我的程序集将在进程中托管 - 我从 Framework64 文件夹加载程序集,并从 Program Files 加载 System.IdentityModel 和 System.IdentityModel.Selectors,而不是 Program Files (x86)。
所以,我尝试了 x86 程序集 - 但尝试加载 System.Web 给出了相当神秘的错误:
程序集 'System.Web' 引用程序集 'system.web, version=2.0.0.0,culture=neutral, publickeytoken=b03f5f7f11d50a3a.',当前数据库中不存在。
嗯,是的...我猜 System.Web 可能确实引用了 System.Web。事实证明,StackOverflow已经有了这个问题的答案。虽然没有多大意义,但看起来您需要加载 System.Web 的 Framework64 版本,以及其他所有内容的常规 Framework 版本。
不幸的是,尝试该解决方案让我返回了可怕的 WCF 捕获所有 CommunicationObjectFaultedException。对 WCF 和 IDisposable 的愚蠢感到恼火,我取消了 using 和 Dispose 调用,这样我就可以 - 你知道 - 实际上看到正确的异常:
var p = new MyServiceClient(new CustomBinding(b), new EndpointAddress(uri));
var result = p.Execute(); // Don't Dispose proxy or you'll lose the actual exception.
try {
return result.Values;
} finally {
if (p.State != CommunicationState.Closed) {
if (p.State != CommunicationState.Faulted) {
p.Close();
} else {
p.Abort();
}
}
}
然后我又遇到了另一个 FileLoadException,这次是在 System.Runtime.Serialization 上,再次将我指向无用的 KB 949080。
考虑到这是 x64 的另一种怪异情况,我决定如果要加载 Framework 程序集,我可能还应该加载 Program Files (x86) System.IdentityModel 程序集。
而且 - 你知道什么......它确实有效。运行时的 IntPtr.Size 为 8 个字节......所以我被加载为 x64。将我的程序集标记为 x64(或 x86)将无法部署 - 它仅适用于 AnyCPU。在加载的程序集上运行 corflags 显示 x86 或 x64 版本的位数没有差异,所以我真的不知道问题是什么。但是,以下 CREATE ASSEMBLIES 有效:
create assembly [System.Web]
from 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\System.Web.dll'
with permission_set = UNSAFE
create assembly [System.Messaging]
from 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll'
with permission_set = UNSAFE
create assembly [SMDiagnostics]
from 'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\SMDiagnostics.dll'
with permission_set = UNSAFE
CREATE ASSEMBLY [System.IdentityModel]
from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.dll'
with permission_set = UNSAFE
CREATE ASSEMBLY [System.IdentityModel.Selectors]
from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.Selectors.dll'
with permission_set = UNSAFE
CREATE ASSEMBLY [Microsoft.Transactions.Bridge]
from 'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\Microsoft.Transactions.Bridge.dll'
with permission_set = UNSAFE
然后将我的用户程序集部署为 AnyCPU。YMMV 可能在 x86 版本的 Sql Server 上。
男孩 - 我真的开始对这些东西的黄金时间还没有做好准备感到恼火。我几乎错过了 C 的简单日子。