All checks were successful
Game Ideas deploy / build-test-deploy (push) Successful in 1m28s
Reviewed-on: #36
161 lines
5.5 KiB
C#
161 lines
5.5 KiB
C#
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;
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
|
|
|
namespace GameIdeas.BlazorApp.Services;
|
|
|
|
public class HttpClientService(
|
|
IHttpClientFactory httpClientFactory,
|
|
ILoggerFactory loggerFactory,
|
|
ILocalStorageService localStorage,
|
|
AuthenticationStateProvider stateProvider) : IHttpClientService
|
|
{
|
|
private readonly HttpClient httpClient = httpClientFactory.CreateClient("GameIdeas.WebAPI");
|
|
private readonly ILogger<HttpClientService> logger = loggerFactory.CreateLogger<HttpClientService>();
|
|
|
|
private readonly JsonSerializerOptions _optionsCamelCase = new()
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
|
|
};
|
|
|
|
private readonly JsonSerializerOptions _optionsCaseInsensitive = new()
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
ReferenceHandler = ReferenceHandler.Preserve
|
|
};
|
|
|
|
public async Task<T?> PostAsync<T>(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<T>(response, ResourcesKey.ErrorWhenPostingData);
|
|
}
|
|
|
|
|
|
public async Task<T?> PutAsync<T>(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<T>(response, ResourcesKey.ErrorWhenPutingData);
|
|
}
|
|
|
|
public async Task<T?> DeleteAsync<T>(string? url)
|
|
{
|
|
await SetAuthorizationHeader();
|
|
var response = await httpClient.DeleteAsync(url);
|
|
|
|
return await GetResultValue<T>(response, ResourcesKey.ErrorWhenDeletingData);
|
|
}
|
|
|
|
public async Task<T?> FetchDataAsync<T>(string? url)
|
|
{
|
|
await SetAuthorizationHeader();
|
|
var response = await httpClient.GetAsync(url);
|
|
|
|
return await GetResultValue<T>(response, ResourcesKey.ErrorWhenFetchingData);
|
|
}
|
|
|
|
public async Task<byte[]?> 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<Stream?> 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<T?> PostFileAsync<T>(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<T>(response, ResourcesKey.ErrorWhenPostingData);
|
|
}
|
|
|
|
private async Task<T?> GetResultValue<T>(HttpResponseMessage response, string errorMessage)
|
|
{
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
try
|
|
{
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
|
|
if (string.IsNullOrWhiteSpace(responseContent))
|
|
{
|
|
return default;
|
|
}
|
|
|
|
var result = JsonSerializer.Deserialize<T>(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 expired = await localStorage.GetItemAsStringAsync(GlobalConstants.LS_EXPIRED_STORAGE_KEY);
|
|
|
|
if (expired == null
|
|
|| (DateTime.TryParse(expired, out DateTime expiration)
|
|
&& expiration < DateTime.UtcNow))
|
|
{
|
|
await ((JwtAuthenticationStateProvider)stateProvider).NotifyUserLogoutAsync();
|
|
return;
|
|
}
|
|
|
|
var token = await localStorage.GetItemAsStringAsync(GlobalConstants.LS_AUTH_STORAGE_KEY);
|
|
httpClient.DefaultRequestHeaders.Authorization =
|
|
new AuthenticationHeaderValue("bearer", token);
|
|
}
|
|
}
|