所以我有一些用户收到此错误
System.MissingMethodException: Method not found: 'Void System.Net.Http.Headers.HttpHeaders.AddWithoutValidation(System.String, System.Collections.Generic.IEnumerable`1<System.String>)'.
at System.Net.Http.HttpHeaderExtensions.CopyTo(HttpContentHeaders fromHeaders, HttpContentHeaders toHeaders)
at System.Net.Http.ObjectContent..ctor(Type type, HttpContent content)
at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content)
at Octgn.Site.Api.ApiClient.Login(String username, String password)
我无法在本地重现,但有些人使用我的WPF应用程序最终会出现此错误。经过一些日志挖掘后,我看到了这个
LOADED ASSEMBLY: System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_2.0.0.0__b03f5f7f11d50a3a\System.Net.Http.dll
我已经尝试过改变这个
的csproj<Reference Include="System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.dll</HintPath>
</Reference>
到这个
<Reference Include="System.Net.Http">
<HintPath>..\..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.dll</HintPath>
</Reference>
我也尝试将其添加到app.config文件
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0 - 4.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
这些东西似乎都不想加载与我的项目的exe在同一目录中的dll。我有本地的DLL,我似乎无法避免GAC。这是一个产品,所以它每天都有数百人,所以我希望找到一些解决方案,不要求用户在最后手动在他们的机器上做某事。
我还想用Assembly.Load
或者类似的东西预加载加载代码中的dll,但我不确定这是否会产生影响,我认为会有更多优雅的解决方案。
好的,那么如果我使用ilmerge
http://www.microsoft.com/en-us/download/details.aspx?id=17630将所有这些新程序集合并到一个新程序集中呢?或者GAC是否使用名称空间等?好吧,我正在尝试...当我遇到问题的人来测试它时,我会报告它是否有效。
有什么想法吗?
答案 0 :(得分:2)
如果您正在引用一个strongly named的程序集并且该程序集在GAC中(具有相同的强名称,即版本号和公钥令牌),则.Net框架将始终从GAC加载该程序集,除非该程序集已加载。
如果您有要加载的DLL的副本,那么该DLL 需要具有不同的强名称(或者没有强名称),以便.Net框架可以告诉GAC中的一个是不同的,它应该在其他地方(例如,与您的应用程序一起) - 从事物的声音,这将涉及以某种方式修改该DLL的本地副本,例如remove the strong name
一旦两个dll具有不同的强名称(或者本地名称没有强名称),使用绑定重定向应该可以正常工作。
更新:或者您可以尝试显式加载该程序集的本地副本(例如,使用Assembly.Load)之前.Net框架加载该程序集,在哪种情况下.Net框架可能使用已经加载的那个而不是查看GAC。 (另)
答案 1 :(得分:1)
如果CLR确定GAC中存在足够好的匹配,则无法避免从GAC(*)加载程序集。没有任何本地副本可以帮助您。
(*)你可以尝试甚至不能使用LoadFrom
使用字节:Understanding The CLR Binder
如果程序集加载到LoadFrom上下文中,Binder首先检查Load上下文中是否已存在确切的程序集(相同的标识和位置)。如果是,它将丢弃LoadFrom上下文中的程序集信息,并使用Load上下文中的程序集信息。
通过搜索Suzanne Cook's blogs and related references可以找到有关装配加载的更多信息。
注意:在这种特殊情况下,解决方案很可能在GAC中检测到这个流氓非RTM二进制文件(即通过尝试进行精确调用并检查“丢失方法”异常)并显示带有解决步骤的消息而不是尝试绕过正常的负载策略。
答案 2 :(得分:1)
仅供参考,我在我的机器上找不到方法System.Net.Http.Headers.HttpHeaders.AddWithoutValidation(...)。但是,我看到System.Net.Http.Headers.HttpHeaders.TryAddWithoutValidation(...)。
对我来说,似乎你有一个带有旧方法签名的非RTM版本的DLL(System.Net.Http.dll)。由于大多数用户没有安装,因此.NET将使用本地副本,一切都很好。
有问题的用户可能已经安装了RTM版本(可能与不同的软件包捆绑在一起)。在这种情况下,.NET将使用GAC版本,因为它更新。
我在评论中坚持我的建议,清理你的开发并从非RTM库构建机器,重新编译和重新部署。
答案 3 :(得分:1)
我使用了ilmerge,并将程序集合并到我的库中并绕过它。