Communicate.HttpClient 1.1.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Communicate.HttpClient --version 1.1.1
NuGet\Install-Package Communicate.HttpClient -Version 1.1.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Communicate.HttpClient" Version="1.1.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Communicate.HttpClient --version 1.1.1
#r "nuget: Communicate.HttpClient, 1.1.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Communicate.HttpClient as a Cake Addin
#addin nuget:?package=Communicate.HttpClient&version=1.1.1

// Install Communicate.HttpClient as a Cake Tool
#tool nuget:?package=Communicate.HttpClient&version=1.1.1

Usage

Creating the client

To use the HTTP-client you need to either dependency inject it as a singleton or make the client into a singleton manually. You should in most cases provide one client per base url you want to communicate with. The client is created through the HttpRestClientFactory like this:

private static HttpRestClient<DefaultHttpClientConfiguration> ApiClient { get; set; }

public static HttpRestClient<DefaultHttpClientConfiguration> GetApiClient()
{
        lock (ApiClientLock)
        {
            if (ApiClient == null)
            {
                ApiClient = HttpRestClientFactory.Create(Settings.GetAppSetting("ApiBaseUrl"), 0);
                ApiClient.AddDefaultHeader(HttpRequestHeaders.ContentType, ContentTypes.ApplicationJson);
                ApiClient.AddDefaultHeader(HttpRequestHeaders.Accept, ContentTypes.ApplicationJson);

                ApiClient.SetOauth2BearerAuthentication(Settings.GetAppSetting("OAuthUrl"),
                    Settings.GetAppSetting("OAuth_client_id"),
                    Settings.GetAppSetting("OAuth_client_secret"),
                    Settings.GetAppSetting("OAuth_grant_type"),
                    null,
                    Settings.GetAppSetting("OAuth_resource"));
            }
        }

        return MessageHubApiClient;
}

This method makes the client into a singleton manually. If you use .net core and/or dependency injection you can just inject the client via services.AddSingleton()

Retrying requests

To retry requests you can either specify the default retry count when creating the client like this HttpRestClientFactory.Create("BaseUrl", 4)` This would make requests retry 4 times based on the following default calculation:

    public virtual bool IsTransient(Exception ex)
    {
        if(ex == null)
        {
            return false;
        }
        else if(ex is HttpRestClientResponseException)
        {
            return TransientStatusCodes.Contains(((HttpRestClientResponseException)ex).StatusCode); //Where TransientCodes are: 504, 408, 503, 0
        }
        else if (ex is TaskCanceledException) //Most likely caused by a timeout, probably transient
        {
            return true;
        }
        else if (ex is HttpRequestException)
        {
            return true;
        }
        else
            return false;
    } 

If you want more control over retrying however you can supply the client with a TransientFaultDetectionStrategy this is an interface that specifies exactly which codes are transient. The following is an example of a custom retry strategy:

ITransientFaultDetectionStrategy faultStrat = HttpRestClientFactory.CreateTransientFaultDetectionStrategy((statusCode) =>
{
	if (statusCode == StatusCodes.Status404NotFound)
		return true;
	else if (statusCode == StatusCodes.Status503ServiceUnavailable)
		return true;
	else if (statusCode == StatusCodes.Status502BadGateway)
		return true;
	else if (statusCode == StatusCodes.Status504GatewayTimeout)
		return true;
	return true;

}, isExceptionTransient: true);

All fault strategies are retried with an exponential interval calculated thus TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); with a timeout of 30 seconds.

Constants

The above example also uses the packages' internal constants for content type and request headers ApiClient.AddDefaultHeader(HttpRequestHeaders.ContentType, ContentTypes.ApplicationJson), this list of constants makes life easier when specifying return types and header types.

Authorization & Authentication

The client has built in support for Oauth2 and basic auth. The example above adds a OAuth header to every request and automatically manages the life time based on the specified lifetime of the token. This functionality need to be imported specifically through using Communicate.Http.OAuth;.

Serializers

The client returns a string by default or an object if you use the type specification on the method, ie. await ApiClient.Post<MyCustomType>("content"); If the object needs to be serialized from something other than JSON you can specify this when creating the client from the factory like so

            OAuthClient.UseFormUrlDeserializer(); //Specifies the deserialization type when receiving response objects
            OAuthClient.UseFormUrlSerializer(); //Specifies the serialization type on outbound when sending the request

The client currently supports JSON (Default), XML and URL content serializers. As specified below you can provide your own serializer by overriding the configuration.

Using the client

To use the client simply get the client and use the preferred verb like this:

HttpRestClient<DefaultHttpClientConfiguration> httpClient = HttpClientHelper.ApiClient();
mappedMsg = await httpClient.Post<string>("url", request);

If you are in need of a verb the client does not support or need more control over your request a Custom method is available for use like this:

await httpClient.Custom(HttpMethod.Options, "Url", "new message");

This method is not to be confused with the SendAsync() method which looks the same as Custom but skips all the internal functionality built into the client. SendAsync() is used when you need to make a request that skips all the options set in the creation of the client and/or you need total control over the request itself runtime.

Overriding the configuration

If you need total control over the retry options or ingress and egress serializes you can override the IHttpClientConfiguration. The default implementation looks like this:

/// <summary>
/// Default implementation of IHttpClientConfiguration.
/// By default it uses Json as ingress and egress type.
/// It uses a basic retry policy with exponential backoff, and a timeout duration of 30 seconds.
/// </summary>
public abstract class HttpClientConfiguration : IHttpClientConfiguration
{
    private IHttpContentSerializer GetSerializer(ContentType t)
    {
        if (t == ContentType.Xml)
            return new XmlContentSerializer();
        else if (t == ContentType.Urlencoded)
            return new UrlencodedContentSerializer();
        else if (t == ContentType.FormUrlEncoded)
            return new FormUrlEncodedContentSerializer();
        else
            return new JsonContentSerializer();
    }

    public AsyncRetryPolicy RetryStrategy { get; set; }
    public ITransientFaultDetectionStrategy FaultDetection { get; set; } = new DefaultTransientFaultStrategy();
    public TimeSpan TimeoutDuration { get; set; } = TimeSpan.FromSeconds(30);
    public IHttpContentSerializer Deserializer { get; set; }
    public IHttpContentSerializer Serializer { get; set; }
    public Func<Task<AuthenticationHeaderValue>> Authentication { get; set; }
    public bool RefreshAuthBeforeEachRequest { get; set; } = false;
    public HttpMessageHandler HttpClientHandler { get; set; }
    public Uri BaseAddress { get; set; }

    public void UpdateRetryStrategy(int maxRetries)
    {
        RetryStrategy = Policy.Handle<Exception>(x => FaultDetection.IsTransient(x))
                              .WaitAndRetryAsync(maxRetries, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
    }
}
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Communicate.HttpClient:

Package Downloads
Connxio.Interaction

Facilitates communication towards Connxio services

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.13 155 3/21/2024
1.3.12 475 2/14/2024
1.3.11 84 2/13/2024
1.3.10 84 2/13/2024
1.3.9 77 2/13/2024
1.3.8 84 2/13/2024
1.3.6 152 2/12/2024
1.3.5 79 2/9/2024
1.3.4 74 2/9/2024
1.3.3 84 2/8/2024
1.3.2 153 2/7/2024
1.3.1 199 2/5/2024
1.3.0 87 2/5/2024
1.2.14 1,619 10/26/2023
1.2.13 226 10/16/2023
1.2.12 3,342 12/7/2022
1.2.11 827 6/22/2022
1.2.10 402 6/22/2022
1.2.9 979 5/11/2022
1.2.8 1,391 4/28/2022
1.2.7 390 4/27/2022
1.2.6 497 1/5/2022
1.2.5 1,058 1/4/2022
1.2.4 1,194 8/6/2020
1.2.3 455 8/5/2020
1.2.1 419 8/5/2020
1.2.0 1,061 6/23/2020
1.1.6 1,320 3/3/2020
1.1.4 629 2/17/2020
1.1.3 687 11/13/2019
1.1.2 1,212 8/26/2019
1.1.1 1,105 4/25/2019
1.1.0 601 4/25/2019
1.0.6 638 3/4/2019
1.0.5 550 3/4/2019
1.0.4 550 3/4/2019
1.0.3 662 2/4/2019
1.0.2 1,499 5/4/2018
1.0.1 986 5/3/2018
1.0.0 975 5/2/2018