Search code examples
c#.net-core.net-framework-version.net-4.7.1httpclienthandler

Handle issue "PlatformNotSupportedException" for HttpClientHandler.SslProtocol in .netstandard2.0 project


I have .netstandard2.0 project which is used by two projects. One is .net core project and one is .netframework4.7.1. I'm getting "PlatformNotSupportedException" for HttpClientHandler.SslProtocol while referring my .Netstandard2.0 project in .netframework4.7.1. I know it is not supported in .netframework4.7.1.But I want to skip that code .netframework4.7.1 and don't skip in .netcore.How can I handle this in .netstansard2.0. I don't have access to both .netframework4.7.1 and .net core.I have access only to .netstandard2.0 where the "HttpClientHandler.SslProtocol" using. I could do anything in .netframework4.7.1 and .net core. What I can do in .netstandard2.0? Working fine in .netcore.

This is my code

    private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler() { 
        AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate, 
        ServerCertificateCustomValidationCallback = null, 
        SslProtocols = System.Security.Authentication.SslProtocols.Tls11 
    })
    {
        Timeout = TimeSpan.FromSeconds(45)
    };

Below code is when implemented ihttpclientfactory

    private static readonly Lazy<IHttpClientFactory> httpClientFactoryLazy = new Lazy<IHttpClientFactory>(() =>
    {
        var services = new ServiceCollection();
        services.AddHttpClient("HttpClientFactory", client =>
        {
            client.Timeout = TimeSpan.FromSeconds(15);
        })
          .ConfigurePrimaryHttpMessageHandler(() =>
          {
              var handler = new HttpClientHandler();
              handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
              handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls11;
              return handler;
          });
        var serviceProvider = services.BuildServiceProvider();
        return serviceProvider.GetRequiredService<IHttpClientFactory>();
    });

Can we use below code identify framework version and do the codes accordingly?

private string GetCallingFramework() {

    return RuntimeInformation.FrameworkDescription;
}

Solution

  • To handle the difference between .NET Standard and .NET 4.x, you need to be able to compile the library to target both platforms. To do this, first change your library .csproj file to support multiple target frameworks:

    <PropertyGroup>
        <TargetFrameworks>netstandard20;net471</TargetFrameworks>
      ....
    </PropertyGroup>
    

    Now in your code you can choose how you handle the different frameworks using one of the preprocessor symbols that is defined for you. For example:

    var handler = new HttpClientHandler();
    //snip
    
    #if NETSTANDARD2_0
        handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls11;
    #endif
    
    //snip
    
    #if NET471
        // In .NET 4.x we must use the ServicePointManager class
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
    #endif