为啥 .Net 4.0 构建客户端 DataContracts 会导致 .Net 4.5 应用程序中的 MethodAccessException?
Posted
技术标签:
【中文标题】为啥 .Net 4.0 构建客户端 DataContracts 会导致 .Net 4.5 应用程序中的 MethodAccessException?【英文标题】:Why does .Net 4.0 build of client DataContracts cause MethodAccessException in .Net 4.5 application?为什么 .Net 4.0 构建客户端 DataContracts 会导致 .Net 4.5 应用程序中的 MethodAccessException? 【发布时间】:2015-08-11 13:46:32 【问题描述】:我有一个名为 WebAccounts.dll 的类库,它调用一些(我自己的)WCF Web 服务。我让 Web 服务项目自动构建其数据合同的客户端版本以供其 .net 客户端使用。它构建了 .net 3.5 和 4.0 版本。所以我有:
OMWebServices.dll
OMWebServices.ClientDataContracts35.dll
OMWebServices.ClientDataContracts.dll (.net 4.0 version)
作为我们正在构建的新网站的一部分,我已将 WebAccounts.dll 从 .net 3.5 升级到 4.5。所以我也将它的 ClientDataContracts 引用从 3.5 版本更新到了 4.0 版本,因为它现在可以使用它了。
现在当 WebAccounts 尝试调用服务方法时,我得到一个 MethodAccessException:
通过方法 'WebAccounts.Data.Franchise..ctor(System.String, IdentifierType)' 来访问方法 'WebAccounts.OMConfigService.ConfigurationServiceClient.GetFranchise(System.String, OMWebServices.DataContracts.FranchiseIDType, Boolean)' 失败。
如果我改回 ClientDataContracts35,它会成功运行。令人困惑的是,更改我的数据合约程序集版本会影响我的代码是否可以访问生成的代理方法(它不在 ClientDataContacts 程序集中,并且是公共的)。
我偶然发现了this Question,它说您可以将<xmlSerializer useLegacySerializerGeneration="true"/>
添加到web.config 以修复某种.net 4.5 序列化兼容性问题。我试了一下,它在使用 4.0 ClientDataContracts 时修复了它。但为什么呢?
最后一个转折是,如果我在我的网站项目中跳过使用 WebAccounts,而只是添加一个服务引用并直接调用相同的服务,它甚至可以使用 4.0 ClientDataContracts,而无需添加 useLegacySerializerGeneration 配置。因此,使用 ClientDataContracts (4.0),网站可以直接调用 Web 服务,但调用调用相同 Web 服务的 WebAccounts 会出现异常。我还验证了当从测试项目调用 WebAccounts 以排除网站项目特定的任何内容时,WebAccounts 会出现异常。
谁能解释一下这里发生了什么?
【问题讨论】:
【参考方案1】:在 .NET Framework v4.5 中,XMLSerializer 默认实现已更改为动态代码生成。这种动态代码生成方法的主要好处是它不需要访问硬盘驱动器,这是客户要求的功能之一。但是,它的限制是它不能访问来自其他程序集的非公共成员。这就是您在某些情况下看到 MethodAccessException 的原因。对于不需要此动态代码生成功能的客户,仍然可以通过使用 [this blog post] (http://blogs.msdn.com/b/praburaj/archive/2013/12/06/xmlserializer-compat-switch.aspx) 中记录的“useLegacySerializerGeneration”配置开关来使用 v4.0 序列化程序。基本上,两种序列化代码路径都支持。
【讨论】:
以上是关于为啥 .Net 4.0 构建客户端 DataContracts 会导致 .Net 4.5 应用程序中的 MethodAccessException?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ConcurrentBag<T> 在 .Net (4.0) 中这么慢?我做错了吗?
在 WCF 和 .NET 4.0 中使用 TLS 1.1 或 1.2?
安装了 .NET 4.5 的构建服务器能否成功地将针对 4.0 的项目部署到仅安装了 .NET 4.0 的服务器?