using GameIdeas.Resources; using System.Net.Http.Headers; using System.Text.Json.Serialization; using System.Text.Json; using System.Text; using Blazored.LocalStorage; using GameIdeas.Shared.Constants; namespace GameIdeas.BlazorApp.Services; public class HttpClientService( IHttpClientFactory httpClientFactory, ILoggerFactory loggerFactory, ILocalStorageService localStorage) : IHttpClientService { private readonly HttpClient httpClient = httpClientFactory.CreateClient("GameIdeas.WebAPI"); private readonly ILogger logger = loggerFactory.CreateLogger(); private readonly JsonSerializerOptions _optionsCamelCase = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault }; private readonly JsonSerializerOptions _optionsCaseInsensitive = new() { PropertyNameCaseInsensitive = true, ReferenceHandler = ReferenceHandler.Preserve }; public async Task PostAsync(string url, object data) { await SetAuthorizationHeader(); var jsonContent = JsonSerializer.Serialize(data, _optionsCamelCase); var content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(url, content); return await GetResultValue(response, ResourcesKey.ErrorWhenPostingData); } public async Task PutAsync(string url, object data) { await SetAuthorizationHeader(); var jsonContent = JsonSerializer.Serialize(data, _optionsCamelCase); var content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); var response = await httpClient.PutAsync(url, content); return await GetResultValue(response, ResourcesKey.ErrorWhenPutingData); } public async Task DeleteAsync(string? url) { await SetAuthorizationHeader(); var response = await httpClient.DeleteAsync(url); return await GetResultValue(response, ResourcesKey.ErrorWhenDeletingData); } public async Task FetchDataAsync(string? url) { await SetAuthorizationHeader(); var response = await httpClient.GetAsync(url); return await GetResultValue(response, ResourcesKey.ErrorWhenFetchingData); } public async Task FetchBytesAsync(string? url) { await SetAuthorizationHeader(); var response = await httpClient.GetAsync(url); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsByteArrayAsync(); } throw new HttpRequestException( $"{ResourcesKey.ErrorWhenFetchingData} + StatusCode: {response.StatusCode} " + $"+ Reason: {response.ReasonPhrase}"); } public async Task FetchStreamAsync(string? url) { await SetAuthorizationHeader(); var response = await httpClient.GetAsync(url); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsStreamAsync(); } throw new HttpRequestException($"{ResourcesKey.ErrorWhenFetchingData} + StatusCode: {response.StatusCode} " + $"+ Reason: {response.ReasonPhrase}"); } public async Task PostFileAsync(string? url, Stream fileStream, string fileName, string contentType) { await SetAuthorizationHeader(); using var content = new MultipartFormDataContent(); var streamContent = new StreamContent(fileStream); streamContent.Headers.ContentType = new MediaTypeHeaderValue(contentType); content.Add(streamContent, "file", fileName); var response = await httpClient.PostAsync(url, content); return await GetResultValue(response, ResourcesKey.ErrorWhenPostingData); } private async Task GetResultValue(HttpResponseMessage response, string errorMessage) { if (response.IsSuccessStatusCode) { try { var responseContent = await response.Content.ReadAsStringAsync(); if (string.IsNullOrWhiteSpace(responseContent)) { return default; } var result = JsonSerializer.Deserialize(responseContent, _optionsCaseInsensitive); return result; } catch (Exception ex) { throw new JsonException(ex.Message); } } logger.LogError(ResourcesKey.RequestFailedStatusFormat, response.StatusCode); throw new HttpRequestException( $"{errorMessage} + StatusCode: {response.StatusCode} + Reason: {response.ReasonPhrase}"); } private async Task SetAuthorizationHeader() { var token = await localStorage.GetItemAsStringAsync(GlobalConstants.LS_AUTH_STORAGE_KEY); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token); } }