What I think I will end up doing is to use a singleton class in my central Library project and host only one instance of an HttpClient
(not static) so that for every project making use of this Library will have a separate single instance of this property. I will also implement a Destroyer in order to properly Dispose of the property instance as soon as the calling project terminates.
This however does not solve my problem when having to use an HttpClientHandler
in order to be able to pass Cookies along side my Post requests. Need some more thought in this aspect.
If you think there is a better way or think that this approach will lead to problems, I would appreciate the heads up.
Thanks again :)
The below is the singleton class I created for my central library. Can you help me to convert it to use IHttpClientFactory
instead? Sorry in advance regarding the overkilling overload methods.
public class HttpFunctions
{
#region Class Members
private HttpClientHandler Http_Client_Handler { get; set; }
private HttpClient Http_Client { get; set; }
#endregion
#region Constructor
public HttpFunctions()
{
InitHttpClient();
}
~HttpFunctions()
{
Dispose();
}
#endregion
#region Methods
#region Post
public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequestUsingBearerAuthentication<T1, T2>(accessToken, payload, requestUri, null, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequestUsingBearerAuthentication<T1, T2>(accessToken, payload, requestUri, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequestUsingBearerAuthentication<T1, T2>(accessToken, payload, requestUri, null, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequestUsingBearerAuthentication<T1, T2>(ParseToResponseContract<T1>, accessToken, payload, requestUri, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequestUsingBearerAuthentication<T1, T2>(parseResponseMethod, accessToken, payload, requestUri, null, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequestUsingBearerAuthentication<T1, T2>(parseResponseMethod, accessToken, payload, requestUri, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequestUsingBearerAuthentication<T1, T2>(parseResponseMethod, accessToken, payload, requestUri, null, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
AuthenticationHeaderValue authToken = null;
if (!string.IsNullOrEmpty(accessToken))
authToken = new AuthenticationHeaderValue("Bearer", accessToken);
return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(ParseToResponseContract<T1>, payload, requestUri, authenticationToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
Uri absoluteUri = new Uri(requestUri, UriKind.Absolute);
return PostRequest<T1, T2>(parseResponseMethod, payload, absoluteUri, authenticationToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(ParseToResponseContract<T1>, payload, requestUri, authenticationToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
}
public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
T1 response = new T1();
try
{
Http_Client.DefaultRequestHeaders.Clear();
if (authenticationToken != null)
Http_Client.DefaultRequestHeaders.Authorization = authenticationToken;
if (httpHeaders != null)
{
foreach (Tuple<string, string> httpHeader in httpHeaders)
Http_Client.DefaultRequestHeaders.Add(httpHeader.Item1, httpHeader.Item2);
}
if (cookies != null)
{
foreach (Cookie cookie in cookies)
Http_Client_Handler.CookieContainer.Add(requestUri, cookie);
}
string jsonPayload = JsonConvert.SerializeObject(payload);
using (HttpContent httpContent = new StringContent(jsonPayload, Encoding.UTF8, "application/json"))
{
string failedReason = string.Empty;
bool succeeded = ProcessFunctions.InnerFunctions.PerformUsingRetriesIf_ReturnIsFalse(() =>
{
bool success = false;
using (HttpResponseMessage httpResponse = Http_Client.PostAsync(requestUri, httpContent).Result)
{
if (httpResponse.IsSuccessStatusCode)
{
response = parseResponseMethod(httpResponse);
success = true;
}
else
{
failedReason = httpResponse.ReasonPhrase;
success = false;
}
}
return success;
}, maxRetries, exponentialRetries, baseValue);
if (!succeeded)
throw new Exception(failedReason);
}
}
finally
{
if (cookies != null)
{
foreach (Cookie cookie in cookies)
Http_Client_Handler.CookieContainer.GetCookies(requestUri)
.Cast<Cookie>()
.ToList()
.ForEach(c => c.Expired = true);
}
Http_Client.DefaultRequestHeaders.Clear();
}
return response;
}
#endregion
#region Get
public T1 GetRequestUsingBearerAuthentication<T1>(string accessToken, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequestUsingBearerAuthentication<T1>(accessToken, requestUri, null, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequestUsingBearerAuthentication<T1>(string accessToken, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequestUsingBearerAuthentication<T1>(ParseToResponseContract<T1>, accessToken, requestUri, httpHeaders, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequestUsingBearerAuthentication<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequestUsingBearerAuthentication<T1>(parseResponseMethod, accessToken, requestUri, null, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequestUsingBearerAuthentication<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
AuthenticationHeaderValue authToken = null;
if (!string.IsNullOrEmpty(accessToken))
authToken = new AuthenticationHeaderValue("Bearer", accessToken);
return GetRequest<T1>(parseResponseMethod, requestUri, authToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequest<T1>(requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequest<T1>(ParseToResponseContract<T1>, requestUri, authenticationToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequest<T1>(parseResponseMethod, requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
Uri absoluteUri = new Uri(requestUri, UriKind.Absolute);
return GetRequest<T1>(parseResponseMethod, absoluteUri, authenticationToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequest<T1>(requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequest<T1>(ParseToResponseContract<T1>, requestUri, authenticationToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
return GetRequest<T1>(parseResponseMethod, requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
}
public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
{
T1 response = new T1();
try
{
Http_Client.DefaultRequestHeaders.Clear();
if (authenticationToken != null)
Http_Client.DefaultRequestHeaders.Authorization = authenticationToken;
if (httpHeaders != null)
{
foreach (Tuple<string, string> httpHeader in httpHeaders)
Http_Client.DefaultRequestHeaders.Add(httpHeader.Item1, httpHeader.Item2);
}
string failedReason = string.Empty;
bool succeeded = ProcessFunctions.InnerFunctions.PerformUsingRetriesIf_ReturnIsFalse(() =>
{
bool success = false;
using (HttpResponseMessage httpResponse = Http_Client.GetAsync(requestUri).Result)
{
if (httpResponse.IsSuccessStatusCode)
{
response = parseResponseMethod(httpResponse);
success = true;
}
else
{
failedReason = httpResponse.ReasonPhrase;
success = false;
}
}
return success;
}, maxRetries, exponentialRetries, baseValue);
if (!succeeded)
throw new Exception(failedReason);
}
finally { Http_Client.DefaultRequestHeaders.Clear(); }
return response;
}
#endregion
#region Parse
public T1 ParseToResponseContract<T1>(HttpResponseMessage httpResponse) where T1 : new()
{
T1 results = new T1();
try
{
if (httpResponse.Content.Headers.ContentType.ToString().ToLower().Contains("application/json"))
{
string jsonResponse = httpResponse.Content.ReadAsStringAsync().Result;
using (MemoryStream jsonStreamResponse = new MemoryStream(Encoding.ASCII.GetBytes(jsonResponse)))
{
//DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings()
//{
// //DateTimeFormat = new DateTimeFormat("yyyy-MM-ddTHH:mm:ss"),
// UseSimpleDictionaryFormat = true,
// EmitTypeInformation = EmitTypeInformation.Never
//};
DataContractJsonSerializer dcs = new DataContractJsonSerializer(typeof(T1));
results = (T1)dcs.ReadObject(jsonStreamResponse);
}
}
}
finally { }
return results;
}
#endregion
#endregion
#region Private Methods
private void InitHttpClient()
{
if (Http_Client == null)
{
Http_Client_Handler = new HttpClientHandler() { CookieContainer = new CookieContainer() };
Http_Client = new HttpClient(Http_Client_Handler);
Http_Client.DefaultRequestHeaders.Accept.Clear();
}
}
private void Dispose()
{
if (Http_Client != null)
{
Http_Client.Dispose();
Http_Client = null;
}
if (Http_Client_Handler != null)
{
Http_Client_Handler.Dispose();
Http_Client_Handler = null;
}
}
#endregion
#region Static Properties
private static readonly IHttpFunctions mHttpFunctions = new HttpFunctions();
public static IHttpFunctions InnerFunctions
{
get { return mHttpFunctions; }
}
#endregion
}