using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.IO; using Http.Core.Contexts; using Http.Core.Models; using static Http.Core.Constants.HttpConstants; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using PCUT.Entities.ApiResponse; using PCUT.Entities; namespace Http.Core.Extensions { public static class HttpExtensions { public static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; public static readonly JsonSerializerSettings IgnoreNullJsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore }; public static readonly JsonSerializer DefaultSerializer = JsonSerializer.Create(JsonSerializerSettings); public static string FormatRoute(this string path, params object[] routeParams) { if (string.IsNullOrEmpty(path)) return null; return string.Format(path, routeParams); } public static Task PostAsJsonAsync(this HttpClient client, string requestUri, object content = null, bool ignoreNull = false) { var jsonContent = content != null ? JsonConvert.SerializeObject(content, ignoreNull ? IgnoreNullJsonSerializerSettings : JsonSerializerSettings) : null; var httpContent = jsonContent != null ? new StringContent(jsonContent, Encoding.UTF8, "application/json") : null; return client.PostAsync(requestUri, httpContent); } public static Task PutAsJsonAsync(this HttpClient client, string requestUri, object content = null, bool ignoreNull = false) { var jsonContent = content != null ? JsonConvert.SerializeObject(content, ignoreNull ? IgnoreNullJsonSerializerSettings : JsonSerializerSettings) : null; var httpContent = jsonContent != null ? new StringContent(jsonContent, Encoding.UTF8, "application/json") : null; return client.PutAsync(requestUri, httpContent); } public static Task UploadAsync(this HttpClient client, string requestUri, Stream stream, string name, string filename) { var streamContent = new StreamContent(stream); var httpContent = new MultipartFormDataContent { { streamContent, name, filename } }; return client.PostAsync(requestUri, httpContent); } public static async Task DownloadAsync(this HttpClient client, string requestUri, Stream outputStream) { HttpResponseMessage response = null; var isSuccess = true; try { response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); await response.Content.CopyToAsync(outputStream); } catch { isSuccess = false; } finally { response?.Dispose(); } return isSuccess; } public static async Task LoginAsync(this HttpClient client, LoginRequest loginRequest, string username) { var response = await client.PostAsJsonAsync(Auth.Login, loginRequest); if (response.IsSuccessStatusCode) { var userCredential = await response.DeserializeObjectAsync(); UserContext.Instance.SetValue(userCredential.AccessToken, userCredential.RefreshToken, username); return new LoginResult { Success = true }; } else { var responseContent = await response.DeserializeObjectAsync(ensureSuccess: false); return new LoginResult { Success = false, Message = responseContent.ErrorMessage }; } } public static async Task LogOutAsync(this HttpClient client) { var response = await client.PostAsync(Api.LogOut, null); if (response.IsSuccessStatusCode) { return true; } return false; } public static async Task RefreshTokenAsync(this HttpClient client) { var response = await client.PostAsJsonAsync(Auth.Refresh, new RefreshTokenRequest()); if (response.IsSuccessStatusCode) { var userCredential = await response.DeserializeObjectAsync(); UserContext.Instance.SetValue(userCredential.AccessToken, userCredential.RefreshToken, userCredential.Username); return true; } return false; } public static async Task LoadUserProfileAsync(this HttpClient client) { var response = await client.GetAsync(Api.Profile); if (response.IsSuccessStatusCode) { var content = await response.DeserializeObjectAsync>(); UserContext.Instance.SetProfile(content.Data); } } public static async Task DeserializeObjectAsync(this HttpResponseMessage response, bool ensureSuccess = true) { if (ensureSuccess) response.EnsureSuccessStatusCode(); if (response.StatusCode == System.Net.HttpStatusCode.NoContent) return default; var content = response.Content; if (content.Headers.ContentLength <= 0 || !content.Headers.ContentType.MediaType.Contains("application/json")) return default; var contentStream = await response.Content.ReadAsStreamAsync(); using (var reader = new StreamReader(contentStream)) using (var jsonReader = new JsonTextReader(reader)) { return DefaultSerializer.Deserialize(jsonReader); } } public static StringBuilder AppendFilter(this StringBuilder builder, string key, string op, string value) { if (builder.Length > 0) builder.Append(','); return builder.Append('\"') .Append(key).Append(':') .Append(op).Append(':') .Append(value) .Append('\"'); } public static StringBuilder AppendFilter(this StringBuilder builder, string key, string value) { return builder.AppendFilter(key, "eq", value); } public static StringBuilder BuildFilter(this StringBuilder builder) { return builder.Insert(0, '[').Append(']'); } public class LoginResult { public bool Success { get; set; } [JsonProperty("message")] public string Message { get; set; } = string.Empty; } } }