using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Generic.Agents
{
/// <summary>
/// Base http caller
/// </summary>
public class BaseHttpAgent
{
/// <summary>
/// Sends a get request with the latest token found in the local database
/// </summary>
/// <param name="uri"></param>
/// <param name="token"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
/// <exception cref="ApiException"></exception>
protected static async Task<T> GetWithAuthAsync<T>(string uri, string token)
{
var clientHandler = new HttpClientHandler();
#if DEBUG // When we connect to localhost with https this workaround is used for ignoring certificate problems
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
return true;
};
#endif
using var httpclient = new HttpClient(clientHandler);
httpclient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var url = $"{Constants.ApiUri}{uri}";
var result = await httpclient.GetAsync(url);
if (!result.IsSuccessStatusCode)
throw new ApiException(
$"[{result.StatusCode}] Error sending get request to {uri}",
await result.Content.ReadAsStringAsync().ConfigureAwait(false),
result.StatusCode
);
var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<T>(content);
}
/// <summary>
/// Retrieve a stream for the api
/// </summary>
/// <param name="uri"></param>
/// <param name="token"></param>
/// <returns></returns>
/// <exception cref="ApiException"></exception>
protected static async Task<MemoryStream> GetStreamWithAuthAsync(string uri, string token)
{
var clientHandler = new HttpClientHandler();
#if DEBUG // When we connect to localhost with https this workaround is used for ignoring certificate problems
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
#endif
using var httpclient = new HttpClient(clientHandler);
if (!string.IsNullOrEmpty(token))
httpclient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var url = uri;
var result = await httpclient.GetAsync(url);
if (!result.IsSuccessStatusCode)
throw new ApiException(
$"[{result.StatusCode}] Error sending get request to {uri}",
await result.Content.ReadAsStringAsync().ConfigureAwait(false),
result.StatusCode
);
var ms = new MemoryStream();
await result.Content.CopyToAsync(ms);
return ms;
}
/// <summary>
/// Generic method for posting data
/// </summary>
/// <param name="httpContent"></param>
/// <param name="uri"></param>
/// <param name="token"></param>
/// <typeparam name="T">Object type that will be given back after the post</typeparam>
/// <returns></returns>
/// <exception cref="ApiException"></exception>
protected static async Task<T> PostAsync<T>(HttpContent httpContent, string uri, string token)
{
var clientHandler = new HttpClientHandler();
#if DEBUG // When we connect to localhost with https this workaround is used for ignoring certificate problems
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
#endif
using var httpclient = new HttpClient(clientHandler);
if (!string.IsNullOrEmpty(token))
httpclient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var url = $"{Constants.ApiUri}{uri}";
var result = await httpclient.PostAsync(url, httpContent);
if (!result.IsSuccessStatusCode)
throw new ApiException(
$"[{result.StatusCode}] Error sending post request to {uri} with following httpContent:{httpContent.ReadAsStringAsync().Result}",
await result.Content.ReadAsStringAsync().ConfigureAwait(false),
result.StatusCode
);
var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
return string.IsNullOrEmpty(content) ? default : JsonConvert.DeserializeObject<T>(content);
}
/// <summary>
/// Generic method for posting data
/// </summary>
/// <param name="id"></param>
/// <param name="uri"></param>
/// <param name="token"></param>
/// <returns></returns>
/// <exception cref="ApiException"></exception>
protected static async Task DeleteAsync(HttpContent httpContent, string uri, string token)
{
var clientHandler = new HttpClientHandler();
#if DEBUG // When we connect to localhost with https this workaround is used for ignoring certificate problems
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
#endif
using var httpclient = new HttpClient(clientHandler);
if (!string.IsNullOrEmpty(token))
httpclient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage
{
Method = HttpMethod.Delete,
RequestUri = new Uri($"{Constants.ApiUri}{uri}"),
Content = httpContent
};
var result = await httpclient.SendAsync(request);
if (!result.IsSuccessStatusCode)
throw new ApiException(
$"[{result.StatusCode}] Error sending post request to {uri}",
await result.Content.ReadAsStringAsync().ConfigureAwait(false),
result.StatusCode
);
}
/// <summary>
/// Generic method for posting data
/// </summary>
/// <param name="httpContent"></param>
/// <param name="uri"></param>
/// <param name="token"></param>
/// <typeparam name="T">Object type that will be given back after the post</typeparam>
/// <returns></returns>
/// <exception cref="ApiException"></exception>
protected static async Task<T> PutAsync<T>(HttpContent httpContent, string uri, string token)
{
var clientHandler = new HttpClientHandler();
#if DEBUG // When we connect to localhost with https this workaround is used for ignoring certificate problems
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
#endif
using var httpclient = new HttpClient(clientHandler);
if (!string.IsNullOrEmpty(token))
httpclient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var url = $"{Constants.ApiUri}{uri}";
var result = await httpclient.PutAsync(url, httpContent);
if (!result.IsSuccessStatusCode)
throw new ApiException(
$"[{result.StatusCode}] Error sending post request to {uri} with following httpContent:{httpContent.ReadAsStringAsync().Result}",
await result.Content.ReadAsStringAsync().ConfigureAwait(false),
result.StatusCode
);
var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<T>(content);
}
/// <summary>
/// Generic method for posting data
/// </summary>
/// <param name="id"></param>
/// <param name="uri"></param>
/// <param name="token"></param>
/// <returns></returns>
/// <exception cref="ApiException"></exception>
protected static async Task DeleteAsync(string id, string uri, string token)
{
var clientHandler = new HttpClientHandler();
#if DEBUG // When we connect to localhost with https this workaround is used for ignoring certificate problems
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
#endif
using var httpclient = new HttpClient(clientHandler);
if (!string.IsNullOrEmpty(token))
httpclient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var url = $"{Constants.ApiUri}{uri}/{id}";
var result = await httpclient.DeleteAsync(url, CancellationToken.None);
if (!result.IsSuccessStatusCode)
throw new ApiException(
$"[{result.StatusCode}] Error sending post request to {uri}",
await result.Content.ReadAsStringAsync().ConfigureAwait(false),
result.StatusCode
);
}
}
}
Comments