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 ); } } }