diff --git a/src/Tests/UnitTests/Weather.Core.UnitTests/Queries/GetForecastWeatherHandlerTests.cs b/src/Tests/UnitTests/Weather.Core.UnitTests/Queries/GetForecastWeatherHandlerTests.cs index 83092ea..9514ecd 100644 --- a/src/Tests/UnitTests/Weather.Core.UnitTests/Queries/GetForecastWeatherHandlerTests.cs +++ b/src/Tests/UnitTests/Weather.Core.UnitTests/Queries/GetForecastWeatherHandlerTests.cs @@ -59,7 +59,7 @@ public async Task GetForecastWeather_Failed() var getForecastWeatherQuery = new GetForecastWeatherQuery(1, 1); _getForecastWeatherQueryValidatorMock.Setup(x => x.Validate(It.IsAny())).Returns(new RequestValidationResult { IsValid = true }); - _weatherServiceMock.Setup(x => x.GetForecastWeather(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Fail(errorMessage)); + _weatherServiceMock.Setup(x => x.GetSixteenDayForecastWeather(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Fail(errorMessage)); //Act var result = await _uut.HandleAsync(getForecastWeatherQuery, CancellationToken.None); @@ -69,7 +69,7 @@ public async Task GetForecastWeather_Failed() Assert.Equal(ErrorMessages.ExternalApiError, result.Errors.Single()); Assert.Null(result.Data); _getForecastWeatherQueryValidatorMock.Verify(x => x.Validate(It.Is(y => y.Equals(getForecastWeatherQuery))), Times.Once); - _weatherServiceMock.Verify(x => x.GetForecastWeather(It.Is(y => y.Equals(getForecastWeatherQuery.Location)), It.IsAny()), Times.Once); + _weatherServiceMock.Verify(x => x.GetSixteenDayForecastWeather(It.Is(y => y.Equals(getForecastWeatherQuery.Location)), It.IsAny()), Times.Once); _loggerMock.VerifyLog(LogLevel.Error, LogEvents.ForecastWeathersGet, errorMessage, Times.Once()); } @@ -81,7 +81,7 @@ public async Task GetForecastWeather_ValidationFailed() var forecastWeather = new ForecastWeatherDto(); _getForecastWeatherQueryValidatorMock.Setup(x => x.Validate(It.IsAny())).Returns(new RequestValidationResult { IsValid = true }); - _weatherServiceMock.Setup(x => x.GetForecastWeather(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Ok(forecastWeather)); + _weatherServiceMock.Setup(x => x.GetSixteenDayForecastWeather(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Ok(forecastWeather)); _forecastWeatherValidatorMock.Setup(x => x.Validate(It.IsAny())).Returns(new RequestValidationResult { IsValid = false }); //Act @@ -92,7 +92,7 @@ public async Task GetForecastWeather_ValidationFailed() Assert.Single(result.Errors); Assert.Null(result.Data); _getForecastWeatherQueryValidatorMock.Verify(x => x.Validate(It.Is(y => y.Equals(getForecastWeatherQuery))), Times.Once); - _weatherServiceMock.Verify(x => x.GetForecastWeather(It.Is(y => y.Equals(getForecastWeatherQuery.Location)), It.IsAny()), Times.Once); + _weatherServiceMock.Verify(x => x.GetSixteenDayForecastWeather(It.Is(y => y.Equals(getForecastWeatherQuery.Location)), It.IsAny()), Times.Once); _forecastWeatherValidatorMock.Verify(x => x.Validate(It.Is(y => y.Equals(forecastWeather))), Times.Once); _loggerMock.VerifyLog(LogLevel.Error, LogEvents.ForecastWeathersValidation, Times.Once()); } @@ -105,7 +105,7 @@ public async Task Success() var forecastWeather = new ForecastWeatherDto(); _getForecastWeatherQueryValidatorMock.Setup(x => x.Validate(It.IsAny())).Returns(new RequestValidationResult { IsValid = true }); - _weatherServiceMock.Setup(x => x.GetForecastWeather(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Ok(forecastWeather)); + _weatherServiceMock.Setup(x => x.GetSixteenDayForecastWeather(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Ok(forecastWeather)); _forecastWeatherValidatorMock.Setup(x => x.Validate(It.IsAny())).Returns(new RequestValidationResult { IsValid = true }); //Act @@ -117,7 +117,7 @@ public async Task Success() Assert.NotNull(result.Data); Assert.Equal(forecastWeather, result.Data); _getForecastWeatherQueryValidatorMock.Verify(x => x.Validate(It.Is(y => y.Equals(getForecastWeatherQuery))), Times.Once); - _weatherServiceMock.Verify(x => x.GetForecastWeather(It.Is(y => y.Equals(getForecastWeatherQuery.Location)), It.IsAny()), Times.Once); + _weatherServiceMock.Verify(x => x.GetSixteenDayForecastWeather(It.Is(y => y.Equals(getForecastWeatherQuery.Location)), It.IsAny()), Times.Once); _forecastWeatherValidatorMock.Verify(x => x.Validate(It.Is(y => y.Equals(forecastWeather))), Times.Once); } } diff --git a/src/Tests/UnitTests/Weather.Infrastructure.UnitTests/Services/WeatherServiceTests.cs b/src/Tests/UnitTests/Weather.Infrastructure.UnitTests/Services/WeatherServiceTests.cs index ecfe81a..7b639d5 100644 --- a/src/Tests/UnitTests/Weather.Infrastructure.UnitTests/Services/WeatherServiceTests.cs +++ b/src/Tests/UnitTests/Weather.Infrastructure.UnitTests/Services/WeatherServiceTests.cs @@ -133,7 +133,7 @@ public async Task GetForecastWeather_Failed() _weatherbiClientMock.Setup(x => x.GetSixteenDayForecast(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Fail(failedMessage)); //Act - var result = await _uut.GetForecastWeather(location, CancellationToken.None); + var result = await _uut.GetSixteenDayForecastWeather(location, CancellationToken.None); //Assert Assert.True(result.IsFailed); Assert.Single(result.Errors); @@ -149,7 +149,7 @@ public async Task GetForecastWeather_NullData() _weatherbiClientMock.Setup(x => x.GetSixteenDayForecast(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Ok((Wheaterbit.Client.Dtos.ForecastWeatherDto)null)); //Act - var result = await _uut.GetForecastWeather(location, CancellationToken.None); + var result = await _uut.GetSixteenDayForecastWeather(location, CancellationToken.None); //Assert Assert.True(result.IsFailed); Assert.Single(result.Errors); @@ -165,7 +165,7 @@ public async Task GetForecastWeather_EmptyData() _weatherbiClientMock.Setup(x => x.GetSixteenDayForecast(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Ok(new Wheaterbit.Client.Dtos.ForecastWeatherDto())); //Act - var result = await _uut.GetForecastWeather(location, CancellationToken.None); + var result = await _uut.GetSixteenDayForecastWeather(location, CancellationToken.None); //Assert Assert.True(result.IsFailed); Assert.Single(result.Errors); @@ -193,7 +193,7 @@ public async Task GetForecastWeather_Success() _mapperMock.Setup(x => x.Map(It.IsAny())).Returns(mapResult); //Act - var result = await _uut.GetForecastWeather(location, CancellationToken.None); + var result = await _uut.GetSixteenDayForecastWeather(location, CancellationToken.None); //Assert Assert.True(result.IsSuccess); diff --git a/src/Weather.API/Configuration/ContainerConfigurationExtension.cs b/src/Weather.API/Configuration/ContainerConfigurationExtension.cs deleted file mode 100644 index c35385a..0000000 --- a/src/Weather.API/Configuration/ContainerConfigurationExtension.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Weather.API.Configuration -{ - public static class ContainerConfigurationExtension - { - public static WebApplicationBuilder AddLogging(this WebApplicationBuilder builder) - { - builder.Logging.ClearProviders(); - builder.Logging.AddConsole(); - return builder; - } - } -} diff --git a/src/Weather.API/Ex.cs b/src/Weather.API/Ex.cs new file mode 100644 index 0000000..03ff226 --- /dev/null +++ b/src/Weather.API/Ex.cs @@ -0,0 +1,18 @@ +using SmallApiToolkit.Middleware; +using System.Net; +using System.Runtime.CompilerServices; + +namespace Weather.API +{ + public class Ex : ExceptionMiddleware + { + public Ex(RequestDelegate next, ILogger logger) : base(next, logger) + { + } + + protected override (HttpStatusCode responseCode, string responseMessage) ExtractFromException(Exception generalEx) + { + return base.ExtractFromException(generalEx); + } + } +} diff --git a/src/Weather.API/Program.cs b/src/Weather.API/Program.cs index b981d75..a3455c1 100644 --- a/src/Weather.API/Program.cs +++ b/src/Weather.API/Program.cs @@ -1,7 +1,9 @@ +using Microsoft.FeatureManagement; +using SmallApiToolkit.Extensions; using SmallApiToolkit.Middleware; -using Weather.API.Configuration; using Weather.API.EndpointBuilders; using Weather.Core.Configuration; +using Weather.Domain.FeatureFlags; using Weather.Infrastructure.Configuration; var builder = WebApplication.CreateBuilder(args); @@ -13,6 +15,19 @@ builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +var corsPolicyName = builder.Services.AddCorsByConfiguration(builder.Configuration); + +builder.Services.AddFeatureManagement(builder.Configuration.GetSection(FeatureFlagKeys.FeatureFlagsKey)); + +/*builder.Configuration.AddAzureAppConfiguration(options => +{ + options.Connect("") + .UseFeatureFlags(featureFlagOptions => + { + featureFlagOptions.SetRefreshInterval(TimeSpan.FromMinutes(1)); + }); +});*/ + var app = builder.Build(); if (app.Environment.IsDevelopment()) @@ -21,6 +36,8 @@ app.UseSwaggerUI(); } +app.UseCors(corsPolicyName); + app.UseHttpsRedirection(); app.UseMiddleware(); diff --git a/src/Weather.API/Weather.API.csproj b/src/Weather.API/Weather.API.csproj index c08bff5..6a2c385 100644 --- a/src/Weather.API/Weather.API.csproj +++ b/src/Weather.API/Weather.API.csproj @@ -10,6 +10,8 @@ + + diff --git a/src/Weather.API/appsettings.json b/src/Weather.API/appsettings.json index 9850bb2..710d558 100644 --- a/src/Weather.API/appsettings.json +++ b/src/Weather.API/appsettings.json @@ -5,10 +5,37 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*", "Weatherbit": { "BaseUrl": "https://weatherbit-v1-mashape.p.rapidapi.com", "XRapidAPIKey": "", "XRapidAPIHost": "weatherbit-v1-mashape.p.rapidapi.com" + }, + "UseAzureForFeatureFlags": false, + "FeatureFlags": { + "useFiveDayForecast": true, + "useCelsiusForTemperature": true, + "allowToDeleteFavorites": [ + { + "name": "TimeBiggerThan", + "parameters": { + "value": "9:00" + } + }, + { + "name": "TimeLessThan", + "parameters": { + "value": "17:00" + } + } + ] + }, + "CORS": { + "name": "allowLocalhostOrigins", + "urls": [ + "http://127.0.0.1:4200", + "http://localhost:4200", + "https://127.0.0.1:4200", + "https://localhost:4200" + ] } } diff --git a/src/Weather.Core/Abstractions/IWeatherService.cs b/src/Weather.Core/Abstractions/IWeatherService.cs index 6bd92a4..11de33b 100644 --- a/src/Weather.Core/Abstractions/IWeatherService.cs +++ b/src/Weather.Core/Abstractions/IWeatherService.cs @@ -7,6 +7,7 @@ public interface IWeatherService { Task> GetCurrentWeather(LocationDto locationDto, CancellationToken cancellationToken); - Task> GetForecastWeather(LocationDto locationDto, CancellationToken cancellationToken); + Task> GetSixteenDayForecastWeather(LocationDto locationDto, CancellationToken cancellationToken); + Task> GetFiveDayForecastWeather(LocationDto locationDto, CancellationToken cancellationToken); } } diff --git a/src/Weather.Core/Queries/GetFavoritesHandler.cs b/src/Weather.Core/Queries/GetFavoritesHandler.cs index 22f3d14..419d9c6 100644 --- a/src/Weather.Core/Queries/GetFavoritesHandler.cs +++ b/src/Weather.Core/Queries/GetFavoritesHandler.cs @@ -1,6 +1,7 @@ using Ardalis.GuardClauses; using FluentResults; using Microsoft.Extensions.Logging; +using Microsoft.FeatureManagement; using SmallApiToolkit.Core.Extensions; using SmallApiToolkit.Core.RequestHandlers; using SmallApiToolkit.Core.Response; diff --git a/src/Weather.Core/Queries/GetForecastWeatherHandler.cs b/src/Weather.Core/Queries/GetForecastWeatherHandler.cs index 7f7bd79..e7ec87d 100644 --- a/src/Weather.Core/Queries/GetForecastWeatherHandler.cs +++ b/src/Weather.Core/Queries/GetForecastWeatherHandler.cs @@ -1,5 +1,7 @@ using Ardalis.GuardClauses; +using FluentResults; using Microsoft.Extensions.Logging; +using Microsoft.FeatureManagement; using SmallApiToolkit.Core.Extensions; using SmallApiToolkit.Core.RequestHandlers; using SmallApiToolkit.Core.Response; @@ -8,6 +10,7 @@ using Weather.Core.Resources; using Weather.Domain.Dtos; using Weather.Domain.Extensions; +using Weather.Domain.FeatureFlags; using Weather.Domain.Logging; using Weather.Domain.Queries; using Weather.Domain.Resources; @@ -19,20 +22,23 @@ internal sealed class GetForecastWeatherHandler : ValidationHttpRequestHandler _forecastWeatherValidator; private readonly IWeatherService _weatherService; private readonly ILogger _logger; + private readonly IFeatureManager _featureManager; public GetForecastWeatherHandler( IRequestValidator getForecastWeatherQueryValidator, IWeatherService weatherService, IRequestValidator forecastWeatherValidator, - ILogger logger) + ILogger logger, + IFeatureManager featureManager) : base(getForecastWeatherQueryValidator) { _weatherService = Guard.Against.Null(weatherService); _forecastWeatherValidator = Guard.Against.Null(forecastWeatherValidator); _logger = Guard.Against.Null(logger); + _featureManager = Guard.Against.Null(featureManager); } protected override async Task> HandleValidRequestAsync(GetForecastWeatherQuery request, CancellationToken cancellationToken) { - var forecastResult = await _weatherService.GetForecastWeather(request.Location, cancellationToken); + var forecastResult = await GetForecastWeatherAsync(request, cancellationToken); if(forecastResult.IsFailed) { @@ -49,5 +55,10 @@ protected override async Task> HandleValidR return HttpDataResponses.AsOK(forecastResult.Value); } + + private async Task> GetForecastWeatherAsync(GetForecastWeatherQuery request, CancellationToken cancellationToken) + => await _featureManager.IsEnabledAsync(FeatureFlagKeys.UseFiveDayForecast) ? + await _weatherService.GetFiveDayForecastWeather(request.Location, cancellationToken) : + await _weatherService.GetSixteenDayForecastWeather(request.Location, cancellationToken); } } diff --git a/src/Weather.Core/Weather.Core.csproj b/src/Weather.Core/Weather.Core.csproj index 0e1bcbf..5d2df6e 100644 --- a/src/Weather.Core/Weather.Core.csproj +++ b/src/Weather.Core/Weather.Core.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Weather.Domain/Dtos/ForecastWeatherDto.cs b/src/Weather.Domain/Dtos/ForecastWeatherDto.cs index 666ce61..b5cf840 100644 --- a/src/Weather.Domain/Dtos/ForecastWeatherDto.cs +++ b/src/Weather.Domain/Dtos/ForecastWeatherDto.cs @@ -2,7 +2,7 @@ { public sealed class ForecastWeatherDto { - public IReadOnlyCollection ForecastTemperatures { get; init; } = new List(); + public IReadOnlyCollection ForecastTemperatures { get; init; } = []; public string CityName { get; init; } = string.Empty; } diff --git a/src/Weather.Domain/Extensions/CelsiusExtensions.cs b/src/Weather.Domain/Extensions/CelsiusExtensions.cs new file mode 100644 index 0000000..4a96693 --- /dev/null +++ b/src/Weather.Domain/Extensions/CelsiusExtensions.cs @@ -0,0 +1,9 @@ +namespace Weather.Domain.Extensions +{ + public static class CelsiusExtensions + { + private const double FahrenheitCelsiusConst = 33.8; + public static double ToCelsius(double fahrenheit) + => fahrenheit * FahrenheitCelsiusConst; + } +} diff --git a/src/Weather.Domain/FeatureFlags/FeatureFlagKeys.cs b/src/Weather.Domain/FeatureFlags/FeatureFlagKeys.cs new file mode 100644 index 0000000..14c7dec --- /dev/null +++ b/src/Weather.Domain/FeatureFlags/FeatureFlagKeys.cs @@ -0,0 +1,9 @@ +namespace Weather.Domain.FeatureFlags +{ + public static class FeatureFlagKeys + { + public static readonly string FeatureFlagsKey = "FeatureFlags"; + public static readonly string UseFiveDayForecast = "useFiveDayForecast"; + public static readonly string UseCelsiusForTemperature = "useCelsiusForTemperature"; + } +} diff --git a/src/Weather.Infrastructure/Services/WeatherService.cs b/src/Weather.Infrastructure/Services/WeatherService.cs index 531ae94..70074e5 100644 --- a/src/Weather.Infrastructure/Services/WeatherService.cs +++ b/src/Weather.Infrastructure/Services/WeatherService.cs @@ -41,9 +41,15 @@ public async Task> GetCurrentWeather(LocationDto locat return _mapper.Map(currentWeatherResult.Value.Data.Single()); } - public async Task> GetForecastWeather(LocationDto locationDto, CancellationToken cancellationToken) + public async Task> GetFiveDayForecastWeather(LocationDto locationDto, CancellationToken cancellationToken) + => await GetForecastWeather(_weatherbitHttpClient.GetFiveDayForecast(locationDto.Latitude, locationDto.Longitude, cancellationToken)); + + public async Task> GetSixteenDayForecastWeather(LocationDto locationDto, CancellationToken cancellationToken) + => await GetForecastWeather(_weatherbitHttpClient.GetSixteenDayForecast(locationDto.Latitude, locationDto.Longitude, cancellationToken)); + + private async Task> GetForecastWeather(Task> getData) { - var forecastWeatherResult = await _weatherbitHttpClient.GetSixteenDayForecast(locationDto.Latitude, locationDto.Longitude, cancellationToken); + var forecastWeatherResult = await getData; if (forecastWeatherResult.IsFailed) { return Result.Fail(forecastWeatherResult.Errors); diff --git a/src/Wheaterbit.Client/Abstractions/IJsonSerializerSettingsFactory.cs b/src/Wheaterbit.Client/Abstractions/IJsonSerializerSettingsFactory.cs index ae4c957..d9f0a35 100644 --- a/src/Wheaterbit.Client/Abstractions/IJsonSerializerSettingsFactory.cs +++ b/src/Wheaterbit.Client/Abstractions/IJsonSerializerSettingsFactory.cs @@ -5,5 +5,6 @@ namespace Wheaterbit.Client.Abstractions public interface IJsonSerializerSettingsFactory { JsonSerializerSettings Create(); + JsonSerializerSettings CreateWithHoursOnly(); } } diff --git a/src/Wheaterbit.Client/Abstractions/IWeatherbitHttpClient.cs b/src/Wheaterbit.Client/Abstractions/IWeatherbitHttpClient.cs index 1f0b29c..b968309 100644 --- a/src/Wheaterbit.Client/Abstractions/IWeatherbitHttpClient.cs +++ b/src/Wheaterbit.Client/Abstractions/IWeatherbitHttpClient.cs @@ -7,5 +7,6 @@ public interface IWeatherbitHttpClient { Task> GetSixteenDayForecast(double latitude, double longitude, CancellationToken cancellationToken); Task> GetCurrentWeather(double latitude, double longitude, CancellationToken cancellationToken); + Task> GetFiveDayForecast(double latitude, double longitude, CancellationToken cancellationToken); } } diff --git a/src/Wheaterbit.Client/Dtos/ForecastTemperatureDto.cs b/src/Wheaterbit.Client/Dtos/ForecastTemperatureDto.cs index f740a2c..cb06478 100644 --- a/src/Wheaterbit.Client/Dtos/ForecastTemperatureDto.cs +++ b/src/Wheaterbit.Client/Dtos/ForecastTemperatureDto.cs @@ -2,7 +2,7 @@ { public sealed class ForecastTemperatureDto { - public double temp { get; init; } - public DateTime datetime { get; init; } + public double? temp { get; init; } + public DateTime? datetime { get; init; } } } diff --git a/src/Wheaterbit.Client/Dtos/ForecastWeatherDto.cs b/src/Wheaterbit.Client/Dtos/ForecastWeatherDto.cs index 5125c19..f95d29f 100644 --- a/src/Wheaterbit.Client/Dtos/ForecastWeatherDto.cs +++ b/src/Wheaterbit.Client/Dtos/ForecastWeatherDto.cs @@ -2,8 +2,8 @@ { public sealed class ForecastWeatherDto { - public IReadOnlyCollection Data { get; init; } = new List(); + public IReadOnlyCollection? Data { get; init; } = []; - public string city_name { get; init; } = string.Empty; + public string? city_name { get; init; } = string.Empty; } } diff --git a/src/Wheaterbit.Client/Factories/JsonSerializerSettingsFactory.cs b/src/Wheaterbit.Client/Factories/JsonSerializerSettingsFactory.cs index 8dff9d4..b818d54 100644 --- a/src/Wheaterbit.Client/Factories/JsonSerializerSettingsFactory.cs +++ b/src/Wheaterbit.Client/Factories/JsonSerializerSettingsFactory.cs @@ -12,5 +12,13 @@ public JsonSerializerSettings Create() DateFormatString = "yyyy-MM-dd hh:mm" }; } + + public JsonSerializerSettings CreateWithHoursOnly() + { + return new JsonSerializerSettings + { + DateFormatString = "yyyy-MM-dd:HH", + }; + } } } diff --git a/src/Wheaterbit.Client/WeatherbitHttpClient.cs b/src/Wheaterbit.Client/WeatherbitHttpClient.cs index 519483d..ce50d8d 100644 --- a/src/Wheaterbit.Client/WeatherbitHttpClient.cs +++ b/src/Wheaterbit.Client/WeatherbitHttpClient.cs @@ -53,7 +53,23 @@ public async Task> GetSixteenDayForecast(double latit } }; - return await SendAsyncSave(request, cancellationToken); + return await SendAsyncSave(request, _jsonSerializerSettingsFactory.Create(), cancellationToken); + } + + public async Task> GetFiveDayForecast(double latitude, double longitude, CancellationToken cancellationToken) + { + var request = new HttpRequestMessage + { + Method = HttpMethod.Get, + RequestUri = new Uri($"{_options.Value.BaseUrl}/forecast/3hourly?lat={latitude}&lon={longitude}&units=imperial&lang=en"), + Headers = + { + { XRapidAPIHostHeader, _options.Value.XRapidAPIHost }, + { XRapidAPIKeyHeader, _options.Value.XRapidAPIKey }, + } + }; + + return await SendAsyncSave(request, _jsonSerializerSettingsFactory.CreateWithHoursOnly(), cancellationToken); } public async Task> GetCurrentWeather(double latitude, double longitude, CancellationToken cancellationToken) @@ -69,14 +85,14 @@ public async Task> GetCurrentWeather(double latitu } }; - return await SendAsyncSave(request, cancellationToken); + return await SendAsyncSave(request, _jsonSerializerSettingsFactory.Create(), cancellationToken); } - private async Task> SendAsyncSave(HttpRequestMessage requestMessage, CancellationToken cancellationToken) + private async Task> SendAsyncSave(HttpRequestMessage requestMessage, JsonSerializerSettings jsonSerializerSettings, CancellationToken cancellationToken) { try { - return await SendAsync(requestMessage, cancellationToken); + return await SendAsync(requestMessage, jsonSerializerSettings, cancellationToken); } catch (Exception ex) { @@ -84,7 +100,7 @@ private async Task> SendAsyncSave(HttpRequestMessage requestMessage } } - private async Task> SendAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken) + private async Task> SendAsync(HttpRequestMessage requestMessage, JsonSerializerSettings jsonSerializerSettings, CancellationToken cancellationToken) { using var response = await _httpClient.SendAsync(requestMessage, cancellationToken); if (!response.IsSuccessStatusCode) @@ -94,7 +110,7 @@ private async Task> SendAsync(HttpRequestMessage requestMessage, Ca var resultContent = await response.Content.ReadAsStringAsync(); - var result = JsonConvert.DeserializeObject(resultContent, _jsonSerializerSettingsFactory.Create()); + var result = JsonConvert.DeserializeObject(resultContent, jsonSerializerSettings); if(result is null) { return Result.Fail($"Failed to deserialize response.");