namespace LaaProduction.Http { using LaaProduction.Http.Interfaces; using Newtonsoft.Json; using RestSharp; using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; public class HttpClient : IHttpClient { private readonly System.Net.Http.HttpClient httpClient; private readonly string routePrefix; public HttpClient(string baseURI, string routePrefix) { var httpHandler = new HttpClientHandler { UseDefaultCredentials = true, }; this.httpClient = new System.Net.Http.HttpClient(httpHandler) { BaseAddress = new Uri(baseURI, UriKind.Absolute) }; this.routePrefix = routePrefix.TrimEnd('/'); } public static IHttpClient CreateHttpClient(string baseURI, string routePrefix) => new HttpClient(baseURI, routePrefix); public IHttpMessage Delete(string route, bool full = false) => new HttpMessage(this, HttpMethod.Delete, this.Route(route, full)); public T DELETE(string route, object query = null) { try { route = new URIHelper(route) .AddQuery(query) .ToString(); var uri = new Uri($"{this.routePrefix}/{route}", UriKind.Relative); var request = new RestRequest(uri, Method.Delete); return new RestClient(this.httpClient).Delete(request); } catch (Exception) // TODO: Exception logging { return default(T); } } public IHttpMessage Get(string route, bool full = false) => new HttpMessage(this, HttpMethod.Get, this.Route(route, full)); public T GET(string route, object query = null) { try { route = new URIHelper(route) .AddQuery(query) .ToString(); var uri = new Uri($"{this.routePrefix}/{route}", UriKind.Relative); var request = new RestRequest(uri, Method.Get); return new RestClient(this.httpClient).Get(request); } catch (Exception) // TODO: Exception logging { return default(T); } } public IHttpMessage Options(string route, bool full = false) => new HttpMessage(this, HttpMethod.Options, this.Route(route, full)); public IHttpMessage Post(string route, bool full = false) => new HttpMessage(this, HttpMethod.Post, this.Route(route, full)); public T POST(string route, object body = null) { try { route = new URIHelper(route).ToString(); var uri = new Uri($"{this.routePrefix}/{route}", UriKind.Relative); var request = new RestRequest(uri, Method.Post); if (body != null) { request.AddBody(body, ContentType.Json); } return new RestClient(this.httpClient).Post(request); } catch (Exception) // TODO: Exception logging { return default(T); } } public IHttpMessage Put(string route, bool full = false) => new HttpMessage(this, HttpMethod.Put, this.Route(route, full)); public T PUT(string route, object body = null) { try { route = new URIHelper(route).ToString(); var uri = new Uri($"{this.routePrefix}/{route}", UriKind.Relative); var request = new RestRequest(uri, Method.Put); if (body != null) { request.AddBody(body, ContentType.Json); } return new RestClient(this.httpClient).Put(request); } catch (Exception) // TODO: Exception logging { return default(T); } } internal async Task> SendAsync(HttpMessage fluentHttpRequestMessage) { var httpResult = new HttpResponse(); using (fluentHttpRequestMessage) { using (var httpResponseMessage = await this.httpClient.SendAsync(fluentHttpRequestMessage)) { if (httpResponseMessage.Content is HttpContent httpContent) { var contentString = await httpContent.ReadAsStringAsync(); try { if (httpResponseMessage.IsSuccessStatusCode) { httpResult.Value = JsonConvert.DeserializeObject(contentString); httpResult.Succeeded = httpResponseMessage.IsSuccessStatusCode && httpResult != null; } else { httpResult.Errors = JsonConvert.DeserializeObject>(contentString); } } catch (Exception e) { httpResult.Succeeded = false; httpResult.Message = JsonConvert.SerializeObject(new { HttpContent = contentString, Exception = e.ToString(), InnerException = e.InnerException?.ToString() }); } } } } return httpResult; } private string Route(string route, bool full) { return full ? route : $"{routePrefix}/{route.TrimStart('/')}"; } } }