System.Net.Http 4.2.0.0未找到的奇怪问题

167

我有一个奇怪的问题,让我感到很疯狂...

我有一个简单的类库项目(完整的.NET框架,4.6.1),其中包含围绕Cosmos DB的功能的包装器类。因此,我将“Microsoft.Azure.DocumentDB” NuGet包1.19.1添加到了这个项目中。除此之外,我还引用了“Newtonsoft.Json” NuGet包10.0.3,以及一些“Microsoft.Diagnostics.EventFlow.*” NuGet包。

到目前为止,一切都可以编译而没有任何错误。

但是,一旦我使用一个简单的Service Fabric无状态服务(完整的.NET Framework 4.6.1)调用我的包装器类,并尝试执行以下代码行:

_docClient = new DocumentClient(new Uri(cosmosDbEndpointUrl), cosmosDbAuthKey);

我在运行时遇到了这个奇怪的错误:

System.IO.FileNotFoundException 异常 HResult=0x80070002
Message=无法加载文件或程序集“System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统 找不到指定的文件。
Source= StackTrace: at Microsoft.Azure.Documents.Client.DocumentClient.Initialize(Uri serviceEndpoint, ConnectionPolicy connectionPolicy, Nullable1 desiredConsistencyLevel) at Microsoft.Azure.Documents.Client.DocumentClient..ctor(Uri serviceEndpoint, String authKeyOrResourceToken, ConnectionPolicy connectionPolicy, Nullable1 desiredConsistencyLevel)

Inner Exception 1: FileNotFoundException: 无法加载文件或程序集“System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个 依赖项。系统找不到指定的文件。

我完全不知道为什么根本找不到 System.Net.Http 程序集——我的类库项目甚至有对 .Net Framework 程序集 “System.Net.Http 4.0.0.0”的引用。

我也不理解为什么会有这个奇怪的绑定重定向到 4.2.0.0——这是从哪里来的呢?

为了解决这个问题,我尝试在 Service Fabric 服务的 app.config 中添加以下重定向:

但是仍然没有任何改变,我仍然在运行时遇到了这个错误。

有人知道原因吗?有人碰到过类似的问题吗?


我回答了这个问题:https://dev59.com/Fanka4cB1Zd3GeqPP45o#63031440 - Mahdi
如果前 5 个答案不适用于您,请参见我的答案,了解如何将程序集添加到 web.config 的编译部分。 - CrnaStena
使用VS时,有很多地方需要注意,比如GAC、Temp文件夹、packages文件夹以及隐藏的.AppData文件夹等等。希望微软能像node一样将VS的包都放在node_modules文件夹中,这样所有的文件都可以集中管理。遇到问题时,只需删除该文件夹,运行npm install命令,搞定 - Jeb50
26个回答

170
你面临的问题与Visual Studio有关,尤其是2017版本,它附带了System.Net.Http v4.2.0.0。然而,采用新的方式通过NuGet进行引用,最新版本的System.Net.Http是4.3.3,其中包含dll版本4.1.1.2。
问题在于,在构建时和运行时,VS会忽略你的引用,并尝试引用它所知道的DLL。
解决方法:
- 确保通过NuGet进行任何对System.Net.Http的引用。 - 构建时错误:更改System.Net.Http.dll的扩展名(或将其移动到其他地方...基本上摆脱它),该DLL随VS 2017一起提供(c:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\);如果您使用的是不同版本,则路径会稍微有所不同,但差别不大。 - 运行时错误:添加程序集绑定重定向。
如果你在谷歌上搜一下,你会发现微软有几个关于这个问题的开放问题,所以希望他们将来能够修复这个问题。
更新:

当寻找一些永久性的解决方案来解决构建代理的问题时,注意到如果迁移到新的NuGet PackageReference模型(在.csproj而不是packages.config中),往往效果更好。这里有一个指南链接,告诉你如何进行此升级:https://learn.microsoft.com/en-us/nuget/reference/migrate-packages-config-to-package-reference


49
提醒一下,如果你正在使用.NET 4.7.2,实际上通过删除bindingRedirects可能会解决该问题。 - Alternatex
2
今天升级到4.7.2时遇到了同样的问题。System.IO.Compression和System.Runtime也受到影响。移除绑定重定向解决了问题。 - JB.
12
是的!终于!根据 @Alternatex 和 JB 的说法,对于 4.7.2 版本,删除 bindingRedirects 后就可以了。每次框架更新都需要弄清最新的 System.Net.Http 需要什么操作,真是太麻烦了。 - Ted
答案说,如果你遇到构建错误,应该将来自MSBuild目录的dll处理掉。但我遇到的是运行时错误,我不得不从MSBuild文件夹中删除那个DLL,清理解决方案并重新构建。最终修复了。 - Ganesh Jadhav
我似乎无法将Web项目移动到PackageReference方法,有没有办法? - Muhammad Mamoor Khan
显示剩余3条评论

145

我移除了绑定重定向,这对我有用,你也可以尝试移除它:

<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />

4
去掉bindingRedirect对我解决了这个问题。单元测试没有通过,出现了和原始发布者(OP)相同的错误,现在它们能够正常工作了。 - Edu
2
这是完整的代码行吗?它需要在哪里添加?我的所有其他bindingRedirects都在dependentAssembly标签中。 - Adam
2
这个方法很好用。我想补充一点,如果你的解决方案中有多个项目,请确保对所有项目进行评估并使用此方法解决问题。 - Scooter
此外,“SpecificVersion”属性应设置为“False”,特别是如果您的项目仍使用packages.config方法。 - vts123
“移除绑定重定向”是可以的。但是使用它的是哪个_程序集_?Visual Studio 引用还是 Nuget 引用 - Kiquenet
有人知道为什么这个有效吗?为什么绑定重定向会成为问题? - undefined

28

回答@AndreiU的帖子,以及如何在本地重现运行时错误。

我在部署到Azure时遇到了下面的运行时错误,而不是在本地。

{"Message":"An error has occurred.","ExceptionMessage":"尝试创建类型为'OrderController'的控制器时发生错误。 确保该控制器具有无参数的公共构造函数。","ExceptionType":"System.InvalidOperationException","StackTrace":“ 在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage请求,HttpControllerDescriptor controllerDescriptor,Type controllerType)\r\n 在 System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()","InnerException":{"Message":"An error has occurred.","ExceptionMessage":“无法加载文件或程序集'System.Net.Http,Version=4.2.0.0,Culture=neutral, PublicKeyToken = b03f5f7f11d50a3a'或其某个依赖项。该文件 指定。” ,“ExceptionType”:“System.IO.FileNotFoundException”,“StackTrace”:“ at Company.Project.Service.CompanyIntegrationApiService..ctor(Uri baseAddress)\r\n at Company.Project.BackOffice.Web.Controllers.OrderController..ctor() in C:\projects\company-project\src\Company.Project.BackOffice.Web\Controllers\Order\OrderController.cs:line 30\r\n at lambda_method(Closure )\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)”}}

当我开始查看程序集时,我发现我的Web项目和服务项目针对System.Net.Http的不同版本。

Web项目:

enter image description here

服务项目:

enter image description here

很容易认为这是因为版本不匹配导致的,但关键在于查看错误The system cannot find the file specified.

查看路径属性,我们可以看到Web项目针对.NET Framework程序集,而服务则针对来自Visual Studio 2017的程序集。由于服务器未安装Visual Studio 2017,因此将出现运行时错误。

Web路径:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll

服务路径:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll

只需将 Copy Local 设置为 true,问题就可以得到解决,但并非所有情况都适用。

enter image description here

要在本地机器上重现错误,只需从 Visual Studio 特定文件夹中删除所需的 System.Net.Http.dll。这将导致运行时错误和一些构建错误。解决这些错误后,一切应该正常工作,至少对我来说是这样。

如果您是通过 NuGet 安装了 System.Net.Http,请检查哪个程序集被使用,方法是查看 .csproj 版本。例如,System.Net.Http 4.3.4 给出以下程序集:

<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
  <HintPath>..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath>
  <Private>True</Private>
</Reference>

如果您使用像Jenkins、TeamCity或AppVeyor这样的构建服务器,则运行时缺少的.dll可能也存在于其中。 在这种情况下,使用System.Net.Http的NuGet版本或在本地删除缺少的.dll可能无法解决此问题。 要解决此错误,请查看未找到的版本和特定的PublicKeyToken。 然后根据您的项目,在Web.configApp.config中创建绑定重定向。 在我的情况下,我想使用4.0.0.0代替:

<dependentAssembly>
  <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0" />
</dependentAssembly>

关于这个问题,有一篇不错的 Github 讨论:

https://github.com/dotnet/corefx/issues/22781


6
添加<dependentAssembly> <assemblyIdentity name="System.Net.Http" ......适用于我。谢谢 - Romeo
1
对我也是!谢谢你提供的解决方法!旧版本="0.0.0.0-4.2.0.0" 新版本="4.1.1.3" 因为我正在使用4.1.1.3。 - Pavel Yermalovich
3
重定向到4.0.0.0是让我达到顶峰的原因。谢谢! - Jim G.
1
重定向到下游是危险的!您的项目中存在依赖项,表明它使用4.2版本,但您强制使用4.0版本。如果使用了4.0版本之后引入的任何新属性或方法,则会在难以预测的时间发生运行时故障。 - David Burg
4
GitHub上的链接已失效,但以下讨论看起来包含相关内容:https://github.com/dotnet/runtime/issues/24382 - Hermann.Gruber
显示剩余4条评论

11

我刚使用NuGet安装了System.Net.Http,你可以在这里找到它:

https://www.nuget.org/packages/System.Net.Http/

我正在开发的ASP.NET MVC项目针对的是.NET 4.6.1。在使用Visual Studio 2019中的进行调试时,在我的机器上完美运行。

问题出现在尝试运行部署到Azure的应用程序时。我遇到了这个错误:

无法加载文件或程序集 "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 或它的某一个依赖项。

在我的情况下真正有效的方法是打开.csproj文件并搜索System.Net.Http,如下面的截图所示...

enter image description here

请注意,.csproj文件的版本为4.1.1.3

<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">

<HintPath>实际上指向了NuGet中的..\packages文件夹,也就是说,这是由NuGet安装的真正版本。一旦部署,此特定版本也将在服务器端还原,然后使用绑定重定向应该可以解决问题。

...因此,在Web.config中,绑定重定向应该像这样提及此特定版本:

<dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.1.1.3" />
</dependentAssembly>

在我提交了几次到 Azure Kudu 后,这解决了我的问题。Azure网站最终无错误地启动。


6
我解决这个问题的方法是从 web.config 中删除所有绑定,然后执行 Update-Package -reinstall 命令。这样可以移除很多不必要的旧绑定,并且有效地进行了清理。

4

我相信答案的一部分可以在微软的文档中找到。

当您使用Visual Studio创建针对.NET Framework 4.5.1或更高版本的桌面应用程序时,该应用程序会使用自动绑定重定向。

正如@Vivek Sharma的答案所指出的那样,删除:

<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />

我在我的应用程序中解决了3个这样的问题。例如,当您使用PowerShell检查DLL时:

 ([system.reflection.assembly]::loadfile("C:\MyApp\bin\System.Net.Sockets.dll")).FullName

输出

System.Net.Sockets, Version=4.0.0.0

显然,将绑定重定向到 4.2.0.0 不会起作用,因为我们将 4.0.0.0 输出到 bin 目录中。

还值得检查 GAC,看看程序集是否也缺失在那里:

 gacutil -l System.Net.Sockets

在我的情况下,特定版本也没有出现在全局程序集缓存中。如果DLL在全局程序集缓存中,则应该在程序集绑定过程中找到

3

除了上述众多建议,以下是对我有用的方法:

  1. Remove Nuget package 4.3.4 (I had to downgrade another package that required it)

  2. Add System.Net.Http as Reference (version 4.2.0.0)

  3. Remove bindingRedirect

  4. Add System.Net.Http to the compilation section in Web.config(s).

    <system.web>
      <compilation debug="false" targetFramework="4.8">
        <assemblies>
          <add assembly="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
        </assemblies>
      </compilation>
      <httpRuntime targetFramework="4.8"/>
    </system.web>
    
如果您有 Areas,请将其添加到它们的 Web.config 文件中。至少我在我的代码中是这样做的。

这解决了我的问题,关于本地 VS 可以工作但在 Azure DevOps 上不能工作的。 - aclalex

2

Andrei U的回答拯救了我。然而,他的推理与我的情况不符。

对于和我处境相同的人:

这是一个运行时错误(不是编译时),编译成功,但只能在一台计算机上工作,而不能在服务器上工作。

解决方案:

  • 添加System.Net.Http包。
  • 在构建服务器上将文件重命名为:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7.2\System.Net.Http.dll(例如将其重命名为:System.Net.Http.dll.BAK)。

我没有,也仍然没有为此dll设置程序集重定向。


2

当我将一个web服务部署到我们的服务器上时,遇到了这个错误。该项目针对的是.Net框架4.7.2,而服务器上没有安装这个版本的框架。在服务器上安装4.7.2框架后,问题得到了解决。


这也是我的问题。对于其他版本来说,这是一个经常出现的话题。 - Jason Geiger

2

我遇到了类似的问题,并且经过很多困难解决了它。我正在使用Visual Studio 2019

  1. 删除任何对System.Net.*(任何以System.Net开头的包)的程序集引用
  2. 卸载所有以System.Net.*开头的包
  3. 从程序包管理器安装Microsoft.AspNet.WebApi.Client
  4. 以上步骤应该可以解决您的问题。如果仍然有问题,Intellisense会建议您添加对System.Net.Http的引用,请单击添加引用。
  5. 在我的情况下,它建议添加两个引用System.Net.Http和System.Net.Http.Formatting。添加后,它就可以正常工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接