Search code examples
nuget.net-6.0.net-standard.net-4.8

NETStandard.Library 2.0.3 vs. System.Net.Http 4.3.4 - What should be prefered?


Nuget NETStandard.Library 2.0.3 (Last update 07.05.2018) contains System.Net.Http, Version=4.1.2.0 (https://www.nuget.org/packages/NETStandard.Library/#versions-body-tab)

Nuget itself has 18.12.2018 as Repository Timestamp https://nuget.info/packages/NETStandard.Library/2.0.3

Nuget System.Net.Http 4.3.4 (Last update 09.10.2018) contains (netstandard1.3) System.Net.Http, Version=4.1.1.3 ( https://www.nuget.org/packages/System.Net.Http/#versions-body-tab)

Nuget itself: https://nuget.info/packages/System.Net.Http/4.3.4

What should be prefered - with respect to use it in a library for other applications in .NET Framework 4.8 and .NET 6.0?


Solution

  • IMO, don't use either package. At least, not directly.

    If your project is targeting .NET Framework, reference System.Net.Http from the GAC, which can be done with <Reference Include="System.Net.Http" />. If your project is multi-targeting, then use a condition Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ".

    If your project is targeting .NET5 or above, then the .NET SDK already references System.Net.Http. So don't explicitly reference anything for System.Net.Http.

    If your project is targeting .NETStandard 2.0, then the .NET SDK already references NETStandard.Library, but automatically adds PrivateAssets="all" to the package reference, so that the package doesn't become a dependency if the project is packed, and the package won't be used transitively in ProjectReferences.

    So, if your project targets .NETStandard:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
      </ProjectGroup>
    </Project>
    

    or alternative if your project multi-targets net48 and net6.0:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFrameworks>net48;net6.0</TargetFrameworks>
      </PropertyGroup>
    
      <ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">
        <Reference Include="System.Net.Http" />
      </ItemGroup>
    </Project>
    

    Now you can freely add using System.Net.Http; in any C# file, and at runtime, .NET will use whatever version of System.Net.Http.dll ships with the runtime.

    If you have many projects in your repo, you can put the ItemGroup in a Directory.Build.props or Directory.Build.targets file, then all projects will get it.

    A lot of System.* packages, including System.Net.Http, were published as packages on nuget.org because during .NET Core 1.0, the .NET team was trying a different way to allow customers to get security fixes for system packages. However, the feedback, and also first hand experience, wasn't good, hence why later .NET Standard has the NETStandard.Library meta package for compile-time only (reference assemblies), and now fixing known security vulnerabilities is achieved by installing a newer .NET runtime. All those old System.* packages with version numbers in the 4.x range should be considered legacy, and best avoided.