Skip to content

Instantly share code, notes, and snippets.

@detroitpro
Created May 25, 2022 02:44
Show Gist options
  • Save detroitpro/4c84032098942d531bdf8d1375e6abae to your computer and use it in GitHub Desktop.
Save detroitpro/4c84032098942d531bdf8d1375e6abae to your computer and use it in GitHub Desktop.
public class HttpClientAbstraction : IHttpClientAbstraction
{
public static HttpClient Client = new HttpClient();
public async Task<Result<T>> GetUrlAsync<T>(string url)
{
return await ExecuteAsync<T>(() => Client.GetAsync(url), url);
}
public async Task<Result<T, TT>> GetUrlAsync<T, TT>(string url)
{
return await ExecuteAsync<T, TT>(() => Client.GetAsync(url), url);
}
public async Task<Result<T>> PostAsync<T>(string url, List<KeyValuePair<string, string>> content)
{
return await ExecuteAsync<T>(() => Client.PostAsync(url, new FormUrlEncodedContent(content)), url);
}
public async Task<Result> PostAsync(string url, List<KeyValuePair<string, string>> content)
{
return await ExecuteAsync(() => Client.PostAsync(url, new FormUrlEncodedContent(content)), url);
}
public async Task<Result<T>> PostAsync<T>(string url, string body)
{
return await ExecuteAsync<T>(() => Client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json")), url);
}
public async Task<Result> PostAsync(string url, string body)
{
return await ExecuteAsync(() => Client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json")), url);
}
public async Task<Result> PutAsync(string url, List<KeyValuePair<string, string>> content)
{
return await ExecuteAsync(() => Client.PutAsync(url, new FormUrlEncodedContent(content)), url);
}
public async Task<Result> PutAsync(string url, string body)
{
return await ExecuteAsync(() => Client.PutAsync(url, new StringContent(body, Encoding.UTF8, "application/json")), url);
}
public async Task<Result<T>> PutAsync<T>(string url, string body)
{
return await ExecuteAsync<T>(() => Client.PutAsync(url, new StringContent(body, Encoding.UTF8, "application/json")), url);
}
public async Task<Result<T>> PutAsync<T>(string url, List<KeyValuePair<string, string>> content)
{
return await ExecuteAsync<T>(() => Client.PutAsync(url, new FormUrlEncodedContent(content)), url);
}
public async Task<Result> PatchAsync(string url, List<KeyValuePair<string, string>> content)
{
return await ExecuteAsync(() => Client.PatchAsync(url, new FormUrlEncodedContent(content)), url);
}
public async Task<Result> PatchAsync(string url, string body)
{
return await ExecuteAsync(() => Client.PatchAsync(url, new StringContent(body, Encoding.UTF8, "application/json")), url);
}
public async Task<Result<T>> PatchAsync<T>(string url, string body)
{
return await ExecuteAsync<T>(() => Client.PatchAsync(url, new StringContent(body, Encoding.UTF8, "application/json")), url);
}
public async Task<Result<T>> PatchAsync<T>(string url, List<KeyValuePair<string, string>> content)
{
return await ExecuteAsync<T>(() => Client.PatchAsync(url, new FormUrlEncodedContent(content)), url);
}
public async Task<Result> DeleteAsync(string url)
{
return await ExecuteAsync(() => Client.DeleteAsync(url), url);
}
private static async Task<Result> ExecuteAsync(Func<Task<HttpResponseMessage>> func, string url)
{
Console.WriteLine($"Calling: {url}");
try
{
var response = await func();
if (response.IsSuccessStatusCode)
{
return Result.Success(url);
}
return Result.Error($"Request error: {url}, Response: {JsonConvert.SerializeObject(response)}");
}
catch (Exception e)
{
return Result.Error(e.Message);
}
}
private static async Task<Result<T>> ExecuteAsync<T>(Func<Task<HttpResponseMessage>> func, string url)
{
Console.WriteLine($"Calling: {url}");
try
{
var response = await func();
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var o = JsonConvert.DeserializeObject<T>(content);
return Result<T>.Success(o, url);
}
return Result<T>.Error($"Request error: {url}, Response: {JsonConvert.SerializeObject(response)}");
}
catch (Exception e)
{
return Result<T>.Error(e.Message);
}
}
private static async Task<Result<T, TT>> ExecuteAsync<T, TT>(Func<Task<HttpResponseMessage>> func, string url)
{
Console.WriteLine($"Calling: {url}");
try
{
var response = await func();
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var o = JsonConvert.DeserializeObject<T>(content);
return Result<T, TT>.Success(o, url);
}
if (response.StatusCode == HttpStatusCode.NotFound)
{
var content = await response.Content.ReadAsStringAsync();
var o = JsonConvert.DeserializeObject<TT>(content);
return Result<T, TT>.Error(o);
}
return Result<T, TT>.Error($"Request error: {url}, Response: {JsonConvert.SerializeObject(response)}");
}
catch (Exception e)
{
return Result<T, TT>.Error(e.Message);
}
}
public IHttpClientAbstraction SetBearerAuth(string jwt)
{
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt);
return this;
}
public IHttpClientAbstraction SetSSOWebSystemAuth(string token)
{
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("SSWS", token);
return this;
}
public IHttpClientAbstraction SetMachineAuth(string token)
{
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Machine", token);
return this;
}
public IHttpClientAbstraction SetBasicAuth(string uid, string pass)
{
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic", Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
$"{uid}:{pass}")));
return this;
}
public IHttpClientAbstraction SetHeader(string key, string value)
{
Client.DefaultRequestHeaders.Remove(key);
Client.DefaultRequestHeaders.Add(key, value);
return this;
}
/// <summary>
/// Creates a new client, almost always not required, here for testing
/// </summary>
/// <param name="client"></param>
/// <param name="handler"></param>
/// <returns></returns>
public IHttpClientAbstraction SetHandler(HttpMessageHandler handler)
{
Client = new HttpClient(handler);
return this;
}
/// <summary>
/// This is internal becuase it should only be able to be called by our tests classes, using the Internals.VisiableTo attribute
/// We use this lib for testing the http client: https://github.com/richardszalay/mockhttp
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
internal IHttpClientAbstraction SetClient(HttpClient client)
{
Client = client;
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment