发现 System.Net.Http 冲突问题

58

我的VS解决方案中有几个项目。每当我向其中一个添加"System.Net.Http" NuGet包时,它显示为版本4.2.0.0。然后我做同样的事情,添加相同的NuGet包,但是另一个却显示版本4.1.1.2。

输入图像描述 输入图像描述

然后我收到一个警告:

发现System.Net.Http之间存在冲突

编辑1:

Gathering dependency information took 1.7 sec
Attempting to resolve dependencies for package 'System.Net.Http.4.3.3' with DependencyBehavior 'Lowest'
Resolving dependency information took 0 ms
Resolving actions to install package 'System.Net.Http.4.3.3'
Resolved actions to install package 'System.Net.Http.4.3.3'
Retrieving package 'System.Net.Http 4.3.3' from 'nuget.org'.
Adding package 'System.Net.Http.4.3.3' to folder 'C:\...Service\packages'
Added package 'System.Net.Http.4.3.3' to folder 'C:\...Service\packages'
Added package 'System.Net.Http.4.3.3' to 'packages.config'
Successfully installed 'System.Net.Http 4.3.3' to ....Service
Executing nuget actions took 2.05 sec
Time Elapsed: 00:00:03.8937113
请注意已安装的正确版本,然而 => 属性 => 版本显示为 4.1.1.2
请注意图片中展示的内容:enter image description here

是的,所有的都是4.6.1。 - ShaneKm
你的项目中可能有依赖于4.1.1.2版本的内容,因此Nuget会拉取该版本。最坏的情况是,你可以使用“-Version”命令行选项在另一个项目中安装4.1.1.2版本。 - Charleh
2
我卸载了所有的NuGet包,并从其他项目中删除了所有引用。然后重新添加了System.Net.Http NuGet。但仍然显示4.1.1.2。 - ShaneKm
2
我注意到这种情况发生在创建新的服务布局Stateful项目时。目标框架为4.6.1。当您向该项目添加“System.net.http”NuGet时,它将引用.net.http ver 4.1.1.2。但是,当您添加一个新的类库,针对相同的.net frawork(4.6.1),并执行添加相同NuGet包(System.Net.Http)的相同步骤时。它将引用ver 4.2.0.0。不确定如何解决此问题。 - ShaneKm
显示剩余2条评论
11个回答

80

编辑:这种情况仅在使用.NET Framework时发生。在.NET Core / Standard领域中,最新的System.Net.Http程序集版本似乎始终为4.1.2.0 - 没有可用的4.2.0.0版本。

关于System.Net.Http的问题比这里的答案所暗示的要复杂得多...

  1. 是的,有一个System.Net.Http NuGet包,但不,它不会安装相同程序集的最新版本(它包含System.Net.Http程序集的版本4.1.1.2,而不是4.2.0.0)。
    更新于2022年3月19日:最新的NuGet包版本4.3.4具有程序集版本4.1.1.3,直接安装程序集版本4.2.0.0仍然不可用。
  2. 最新的Microsoft Visual Studio(或Microsoft Visual Studio Build Tools)提供了版本4.2.0.0,但这并不意味着您的.csproj将始终使用它...
  3. 由于某种原因(我还没有理解),使用4.2.0.0的唯一保证方法是引用某些使用它的NuGet包,例如System.Buffers(版本4.5.0对我有效)。

TL;DR:

如果要确保使用System.Net.Http 4.2.0.0程序集,请将System.Buffers 4.5.0+ NuGet引用添加到您的项目中。

参考:


4
这解决了我的问题。我同时运行了一些 .NET 框架和 aspnetcore 项目。 - Reuel Ribeiro
10
这也解决了我的问题。天啊,微软的.NET Core团队,这真是一团糟。我花了将近2天时间在一个引入了.NET标准库的大型项目上尝试解决它。 - Michael Brown
我添加了一个答案,它基于我在这个答案和引用的参考资料中找到的信息,不需要添加像System.Buffers这样的随机引用。虽然有点冗长,但希望能有所帮助。 - Neo
1
真的很令人沮丧的问题,需要一个非常不寻常的解决方法,但我很感激你找到并分享了这个方法。这解决了我的问题。 - WillB3
1
你刚刚让我免于花费更多令人沮丧的时间来消除这些警告。非常感谢你。 - Waescher
五年后偶然发现了这个。正在开发一个针对4.6.1和VS2019的项目。我不明白的是现在建议采用什么方法。我们应该使用Nuget分发的dll还是依赖于MSBuild版本。我查看了“参考资料”中提供的Github链接。在其中一个Github链接中,可能是微软的人提到Nuget方法是一种临时的东西,我们不应再使用它。这正确吗? - Dibzmania

43

在浏览了这里提出的所有解决方案和引用此答案中的内容后,我最终完全解决了这个问题。我认为任何遇到这个问题的人都应该这样做:

  1. 将所有NuGet包更新到最新版本。
  2. 按照此处的说明,将NuGet从packages.config迁移到PackageReference。基本上,对于您解决方案中的每个项目,在“解决方案资源管理器”中,右键单击引用节点或packages.config文件,并选择迁移 packages.config 到 PackageReference...。ASP.NET网站项目必须继续使用packages.config
  • 移除任何未由 NuGet 管理的对 System.Net.Http 的引用(对于使用PackageReference的项目,您应该在解决方案资源管理器中看到 NuGet 图标enter image description here跟随引用)。如果确定您的项目需要 System.Net.Http ,请将删除的 System.Net.Http 引用替换为相应的NuGet包(首先尝试构建不使用它的项目)。对于使用packages.config的项目,请特别注意确保 System.Net.Http 的引用是必需的,并且也要使用NuGet。即使已经使用 NuGet 引用,也可以通过 NuGet 删除和重新添加 System.Net.Http 来帮助(针对所有引用它的项目)。我发现步骤2可能会导致某些位置分散。
  • 根据此处所述的原因升级到 .NET Framework 4.7.2。这是 VS 2019 的一部分。否则,从此处下载或使用 VS 2017 的 Visual Studio Installer。
  • 从所有的 app.configWeb.config 文件中删除全部程序集绑定,然后构建你的解决方案。现在不再需要 app.config 绑定。下一步将重新添加 Web.config 绑定,但是首先删除它们可以确保你没有任何已过时的版本在绑定中。
  • 此时可能会出现其他冲突。对于 ASP.NET 网站项目,在你收到的警告中添加到你的 Web.config 的绑定重定向。对于其他 .NET Framework 应用程序,在你收到警告的引用中,将相应的 NuGet 包添加到你收到警告的项目中,即使该项目在没有添加引用的情况下也能编译。这强制项目使用 NuGet 版本,而不是可能被另一个包引用的本地 .NET Framework 版本。这是由 rsenna 在其上述答案中提到的 .NET Framework 和 .NET Standard 之间的交叉引用所导致的。构建后,你可能需要为进一步的引用重复此步骤。
  • 如果您在添加引用后,发现即使在单元测试期间也会出现运行时异常(由于清单不匹配),则需要从相关的网站项目中删除所有绑定重定向,然后按照步骤6重新添加警告中建议的绑定重定向。

    我花了很多时间系统地尝试解决这个问题,因此我相信上述步骤可以完全解决大多数人的问题,尽管对于一些不寻常的情况可能需要某些横向思考。如果这对您有用(或无效),请告诉我。


    3
    你提到的答案似乎表明,为了避免(大部分?全部?)绑定重定向,我们需要升级到.NET Framework 4.7.2。我觉得这很有说服力,所以支持这个想法。但不幸的是,目前我无法将我们的环境升级到4.7.2版本,因此 System.Buffers 解决方案,即使有些 "随意",仍然是最好的解决方案,至少在我的情况下,现在也是如此。 - rsenna
    2
    @rsenna 是的,将环境升级到4.7.2的要求对我们来说也是一个难点,但这只是启动流程并像往常一样打通繁文缛节的问题。我认为这比短期的hack更好的长期解决方案。 - Neo
    1
    System.Buffers解决方案对我无效,但这个有效。我建议花时间升级,因为我尝试的解决方法不一致。90%的时间它们可以工作,但有时会失败,我无法找出原因。 - JasonlPrice
    @JasonlPrice 谢谢。我在VS 2019中的一个现有ASP.NET网站项目上再次遇到了这个问题,并花费时间使用此过程升级了所有内容,完全解决了它。值得注意的是,特别针对ASP.NET网站项目,步骤2不适用,步骤3具有特定的packages.config说明,因为任何对System.Net.Http的引用都是通过NuGet引用而不是正常程序集引用实现的。 - Neo
    2
    这是对我有效的解决方案: 1- 删除了对 System.Net.Http 的 .Net Framework 的文件引用 2- 将框架更新到 4.7.2,以最大化 .Net Standard 的 API 兼容性。 3- 更新/合并所有 NuGet 包。bin 文件夹包含来自框架而不是 NuGet 版本的 System.Net.Http,因此在运行时崩溃。 - Adam Paquette
    1
    顺便说一句:我们使用的是.NET 4.6.1,在迁移packages.config后,版本不匹配的问题已经解决了。 - Metro Smurf

    14

    当您有对框架System.Net.Http的引用,但其中一个包需要NuGet包System.Net.Http时,往往会出现这种情况。

    请检查是否引用了该程序集,删除它并安装相应的NuGet包。


    1
    我该如何找出哪一个? - ShaneKm
    在执行上述卸载命令后,您是否仍然有对System.Net.Http的引用? - Francesco B.
    这个答案解决了我的System.Net.Http问题。我有一个真正混合的框架引用(4.0.0.0)和包引用(4.1.1.2)。还要注意,包管理器可能仍然安装显示为“4.3.3”(2018年9月)的版本,但在程序集内部,版本号是4.1.1.2。必须在Web/App配置中使用后者的版本号。 - Rob Von Nesselrode

    11

    截至2018年10月9日,有一个新的解决方案可用。

    1. You will need to update all your references to System.Net.Http to the latest version 4.3.4.
    2. You should install the package into your .Net framework solution that is causing the conflict, even if it does not explicitly require the package.
    3. If your project has the new project structure, edit it and make sure it includes the following package reference:

      <PackageReference Include="System.Net.Http" Version="4.3.4" />
      
    4. Search your solution and delete any existing binding redirects for System.Net.Http they will look as follows

      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
      </dependentAssembly>
      
    5. Rebuild, the warning should now be gone and your code should build and run fine


    这对我有效,只需对web.config文件进行单个编辑(第4项)。 - PCG
    2
    System.Net.Http的程序集版本为4.3.4,其版本号为4.1.1.3。至少对于Nuget文件夹中的此dll,“System.Net.Http/4.3.4/lib/net46/System.Net.Http.dll”。 - Matt Bussing

    6
    你可以强制安装指定版本,这样两个项目就可以对齐,或者在输出窗口中找到一条消息,告诉你问题所在或你的依赖关系。 由于官方链接没有列出4.2版本,我会这样做(整个解决方案)。
    Install-Package System.Net.Http -Version 4.1.1
    

    或者对于两个项目都适用

    Get-Project ProjectName | Install-Package System.Net.Http -Version 4.1.1
    

    或者,更好的是(使用最新版本)

    Install-Package System.Net.Http -Version 4.3.3
    

    编辑

    显然你不是第一个遇到这个问题的人。 那么这里的答案怎么样? 基本上,你可以对两个项目的配置文件进行对齐:

      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" />
            <bindingRedirect oldVersion="0.0.0.0-4.1.1.2" newVersion="4.2.0.0" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    

    您可能需要调整令牌值。 以防万一,您能否粘贴两个项目的配置文件?


    2
    仍然无法工作。即使指定了版本号。 - ShaneKm
    请参见Edit1。运行以下命令:Install-Package System.Net.Http -Version 4.3.3 - ShaneKm
    同样的事情。我创建了一个全新的解决方案。添加了Service Fabric Stateful服务。然后只需通过NuGet控制台或添加新的Nuget UI,安装System.Net.Http。它将安装版本4.1.1.2。然后在同一解决方案中添加新的类库,执行相同的步骤。它将添加版本4.2.0.0。因此,Stateful服务项目始终获取版本4.1.1.2,而类库项目获取4.2.0.0。 - ShaneKm
    1
    问题仍然存在,但是在安装了版本为4.1.1.2的Service Fabric项目的app.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.2" /> </dependentAssembly> - ShaneKm
    1
    嗯,我仍然不确定为什么Service Fabric项目会强制安装4.1.1.2版本而不是最新版本。 - ShaneKm
    显示剩余4条评论

    4
    Neo发布的6个步骤帮助我解决了ASP.NET包的问题!谢谢Neo!我处理了一个多星期。
    我想分享一下我根据Neo的帖子实践的个人笔记。
    我有一个ASP.NET Web API项目,目标是.Net Framework 4.6.1
    这是我的做法:
    • 升级到 .Net Framework 4.7.2
    • 将所有NuGet包更新到最新版本。
    • (可选)也可以执行 "update-package -reinstall" 确保所有包与4.7.2关联)
    • 合并包
    • 我没有从 packages.config 迁移到 PackageRefence,因为在ASP.NET中无法这样做。
    • 从需要 System.Net.Http 和其他引用的地方删除了它们,并将它们添加为 NuGet 包。
    • 从 web.config 和 app.config(在.Core、.Tests、.IntegrationTests库中)中删除了所有程序集绑定。
    • 为我们内部的 NuGet 包添加了绑定重定向,这些包的版本号以文本结尾 (n.n.n.n-beta),但只保留数字 (n.n.n.n)。
    • 将此添加到所有 .csproj 文件中:
    <PropertyGroup>
      <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>
    </PropertyGroup>
    
    • 确保解决方案中所有项目的packages.config文件中的包版本相同
      • 确保web.config中的版本相同
      • 如果适用,确保.csproj文件中的版本相同
    • 使用Microsoft.Net.Compilers 3.1.1(更新解决方案中的所有.csproj文件,包括.Tests和.IntegrationTests)
    • 对于使用Redis的数据保护API(DPAPI):
      • 安装Microsoft.AspNetCore.DataProtection.StackExchangeRedis 2.2.5
      • StackExchange.Redis 2.0.601
      • 将System.Numerics.Vectors更新为4.4.0(注意:4.5.0存在一个阻止服务器连接的错误)

    1
    我在使用Azure Worker角色时遇到了这个问题两次。任何对system.net.http的调用都会导致代码挂起,但是Azure没有任何反馈,因此需要花费数小时或数天的时间注释代码才能找到原因,更不用说解决方案了。
    一个简单的技巧为我解决了这个问题。这不是我的解决方案,我大约6个月前就发现了它,但当今天问题再次发生时,我认为值得发布。
    1. 从项目中删除对System.Net.Http的所有引用
    2. 转到"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib"
    3. 创建一个新目录,例如"temphide"
    4. 将所有System.Net.* DLL移动到此目录中
    5. 现在,当您部署时,您的项目将使用Nuget版本,不再有冲突

    1

    我尝试了各种解决方案(删除dependentAssembly或同时指定binding redirect)。但它们都没有起作用。

    然而,对我有效的唯一解决方案是从Visual Studio明确将System.Net.Http(或任何给你版本问题的DLL)的Specific Version设置为False。

    enter image description here


    1

    在各种项目上花费了许多天的时间,试图修复这个经常出现的问题:这里有一个可靠的解决方法,不会在一段时间后失效。已测试通过4.6.1和4.7.2。

    修复过程

    修复您的开发人员机器:

    • 删除所有对nuget包“System.Net.Http”的引用
    • 打开“%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2”目录(根据您的特定版本进行调整)。
      • 位置可能因计算机而异,请参见此答案
    • 在此目录中:找到特殊文件System.Net.Http.dll
    • 在此目录中:将“System.Net.Http.dll”重命名为“System.Net.Http.dll.backup

    在所有开发人员机器上执行此操作。这不会破坏您的机器。

    在您的项目中:只需添加基本的“程序集引用”即可使用“System.Net.Http”。

    在您的可运行项目(Web / CLI)中:您可能需要将项目引用设置为“复制本地”,以便在发布到其他地方时正确地复制dll。

        <Reference Include="System.Net.Http">
          <Private>true</Private>
        </Reference>
    

    在某些情况下,您可以添加此程序集重定向(app.config/web.config):

          <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>
    

    为什么这样做可以解决问题?

    似乎构建过程能够“看到”这个特殊文件的存在。然后构建将生成有问题的引用,这将导致你熟悉的异常。

    通过使文件不可见(由于文件扩展名更改),构建过程将无法执行这些疯狂的操作。

    这个特殊文件是什么?它有什么特别之处吗?

    这个文件是假的。反编译它,你会发现它是空的
    他们只是把它放在那里让我们疯狂 [需要引用]

    位置可能会有所不同:

    • 当安装了 SDK 时:
      • "%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2"
    • 没有 SDK 时:
      • "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib"

    等等,你不能删除系统文件!

    这就是我(和其他人)几年来得出的结论。这个问题每年都会多次出现。这个解决方案并不像你想象的那么糟糕,因为有问题的文件是一个虚假程序集

    了解更多

    这个Github上的dotnet问题包含了大量关于这个问题的信息。这个答案解释了全局问题中的传递依赖现象。这个答案建议删除错误的dll文件。

    糟糕,看起来我部分重复了Steven Elliott的回答。不过我的更详细。


    -1

    只需从不同的项目/类库中删除system.net.http引用,然后再次添加引用即可。


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