From 1aca54cdf0b8e1c40aa6b1988d303dae6205e850 Mon Sep 17 00:00:00 2001 From: Bruno Lins de Oliveira Date: Thu, 12 May 2022 11:56:07 -0700 Subject: [PATCH 1/4] Using non-generic Write operation for ProblemHttpResult --- .../Http.Results/src/HttpResultsHelper.cs | 22 +++++++++++++ .../Http.Results/src/ProblemHttpResult.cs | 3 ++ .../Http.Results/test/ProblemResultTests.cs | 31 ++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/Http/Http.Results/src/HttpResultsHelper.cs b/src/Http/Http.Results/src/HttpResultsHelper.cs index b899467b1d80..6aac2c5b32dd 100644 --- a/src/Http/Http.Results/src/HttpResultsHelper.cs +++ b/src/Http/Http.Results/src/HttpResultsHelper.cs @@ -16,6 +16,28 @@ internal static partial class HttpResultsHelper private const string DefaultContentType = "text/plain; charset=utf-8"; private static readonly Encoding DefaultEncoding = Encoding.UTF8; + public static Task WriteResultAsJsonAsync( + HttpContext httpContext, + ILogger logger, + object? value, + Type valueType, + string? contentType = null, + JsonSerializerOptions? jsonSerializerOptions = null) + { + if (value is null) + { + return Task.CompletedTask; + } + + Log.WritingResultAsJson(logger, valueType.Name); + + return httpContext.Response.WriteAsJsonAsync( + value, + options: jsonSerializerOptions, + type: valueType, + contentType: contentType); + } + public static Task WriteResultAsJsonAsync( HttpContext httpContext, ILogger logger, diff --git a/src/Http/Http.Results/src/ProblemHttpResult.cs b/src/Http/Http.Results/src/ProblemHttpResult.cs index bd7e72ff87aa..a4f53ea65c94 100644 --- a/src/Http/Http.Results/src/ProblemHttpResult.cs +++ b/src/Http/Http.Results/src/ProblemHttpResult.cs @@ -20,6 +20,8 @@ public sealed class ProblemHttpResult : IResult /// The instance to format in the entity body. internal ProblemHttpResult(ProblemDetails problemDetails) { + ArgumentNullException.ThrowIfNull(problemDetails); + ProblemDetails = problemDetails; HttpResultsHelper.ApplyProblemDetailsDefaults(ProblemDetails, statusCode: null); } @@ -57,6 +59,7 @@ public Task ExecuteAsync(HttpContext httpContext) httpContext, logger, value: ProblemDetails, + valueType: ProblemDetails.GetType(), ContentType); } } diff --git a/src/Http/Http.Results/test/ProblemResultTests.cs b/src/Http/Http.Results/test/ProblemResultTests.cs index 4e6c38a5670d..07f55625d1d5 100644 --- a/src/Http/Http.Results/test/ProblemResultTests.cs +++ b/src/Http/Http.Results/test/ProblemResultTests.cs @@ -59,7 +59,6 @@ public async Task ExecuteAsync_UsesDefaults_ForValidationProblemDetails() // Act await result.ExecuteAsync(httpContext); - // Assert Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); stream.Position = 0; @@ -69,6 +68,36 @@ public async Task ExecuteAsync_UsesDefaults_ForValidationProblemDetails() Assert.Equal(StatusCodes.Status400BadRequest, responseDetails.Status); } + [Fact] + public async Task ExecuteAsync_IncludeErrors_ForValidationProblemDetails() + { + // Arrange + var details = new HttpValidationProblemDetails(new Dictionary + { + { "testError", new string[] { "message" } } + }); + + var result = new ProblemHttpResult(details); + var stream = new MemoryStream(); + var httpContext = new DefaultHttpContext() + { + RequestServices = CreateServices(), + Response = + { + Body = stream, + }, + }; + + // Act + await result.ExecuteAsync(httpContext); + // Assert + Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); + stream.Position = 0; + var responseDetails = JsonSerializer.Deserialize(stream); + var error = Assert.Single(responseDetails.Errors); + Assert.Equal("testError", error.Key); + } + [Fact] public async Task ExecuteAsync_GetsStatusCodeFromProblemDetails() { From c49670b330d34b12ee0d97edd7d85e1dde6f8035 Mon Sep 17 00:00:00 2001 From: Bruno Lins de Oliveira Date: Thu, 12 May 2022 14:07:26 -0700 Subject: [PATCH 2/4] Update unit tests --- src/Http/Http.Results/test/ProblemResultTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Http/Http.Results/test/ProblemResultTests.cs b/src/Http/Http.Results/test/ProblemResultTests.cs index 07f55625d1d5..eb21093dadad 100644 --- a/src/Http/Http.Results/test/ProblemResultTests.cs +++ b/src/Http/Http.Results/test/ProblemResultTests.cs @@ -90,10 +90,12 @@ public async Task ExecuteAsync_IncludeErrors_ForValidationProblemDetails() // Act await result.ExecuteAsync(httpContext); + // Assert Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); stream.Position = 0; var responseDetails = JsonSerializer.Deserialize(stream); + Assert.Equal(StatusCodes.Status400BadRequest, responseDetails.Status); var error = Assert.Single(responseDetails.Errors); Assert.Equal("testError", error.Key); } From 8c8ae9e66d33e0a3468b4c6f81d0003dfe4a4a2c Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 12 May 2022 15:15:20 -0700 Subject: [PATCH 3/4] Removing ThrowIfNull --- src/Http/Http.Results/src/ProblemHttpResult.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Http/Http.Results/src/ProblemHttpResult.cs b/src/Http/Http.Results/src/ProblemHttpResult.cs index a4f53ea65c94..c29e7c0af9ee 100644 --- a/src/Http/Http.Results/src/ProblemHttpResult.cs +++ b/src/Http/Http.Results/src/ProblemHttpResult.cs @@ -20,8 +20,6 @@ public sealed class ProblemHttpResult : IResult /// The instance to format in the entity body. internal ProblemHttpResult(ProblemDetails problemDetails) { - ArgumentNullException.ThrowIfNull(problemDetails); - ProblemDetails = problemDetails; HttpResultsHelper.ApplyProblemDetailsDefaults(ProblemDetails, statusCode: null); } From 68ed19fe080d549c2f31a5078ee6842c59bb53e8 Mon Sep 17 00:00:00 2001 From: Bruno Lins de Oliveira Date: Thu, 12 May 2022 21:01:35 -0700 Subject: [PATCH 4/4] PR Feedback --- .../Http.Results/src/HttpResultsHelper.cs | 22 ------------------- .../Http.Results/src/ProblemHttpResult.cs | 3 +-- .../Http.Results/test/ProblemResultTests.cs | 1 + 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/Http/Http.Results/src/HttpResultsHelper.cs b/src/Http/Http.Results/src/HttpResultsHelper.cs index 6aac2c5b32dd..b899467b1d80 100644 --- a/src/Http/Http.Results/src/HttpResultsHelper.cs +++ b/src/Http/Http.Results/src/HttpResultsHelper.cs @@ -16,28 +16,6 @@ internal static partial class HttpResultsHelper private const string DefaultContentType = "text/plain; charset=utf-8"; private static readonly Encoding DefaultEncoding = Encoding.UTF8; - public static Task WriteResultAsJsonAsync( - HttpContext httpContext, - ILogger logger, - object? value, - Type valueType, - string? contentType = null, - JsonSerializerOptions? jsonSerializerOptions = null) - { - if (value is null) - { - return Task.CompletedTask; - } - - Log.WritingResultAsJson(logger, valueType.Name); - - return httpContext.Response.WriteAsJsonAsync( - value, - options: jsonSerializerOptions, - type: valueType, - contentType: contentType); - } - public static Task WriteResultAsJsonAsync( HttpContext httpContext, ILogger logger, diff --git a/src/Http/Http.Results/src/ProblemHttpResult.cs b/src/Http/Http.Results/src/ProblemHttpResult.cs index a4f53ea65c94..2b64a1f122bb 100644 --- a/src/Http/Http.Results/src/ProblemHttpResult.cs +++ b/src/Http/Http.Results/src/ProblemHttpResult.cs @@ -55,11 +55,10 @@ public Task ExecuteAsync(HttpContext httpContext) httpContext.Response.StatusCode = code; } - return HttpResultsHelper.WriteResultAsJsonAsync( + return HttpResultsHelper.WriteResultAsJsonAsync( httpContext, logger, value: ProblemDetails, - valueType: ProblemDetails.GetType(), ContentType); } } diff --git a/src/Http/Http.Results/test/ProblemResultTests.cs b/src/Http/Http.Results/test/ProblemResultTests.cs index eb21093dadad..688bd1ecf7b0 100644 --- a/src/Http/Http.Results/test/ProblemResultTests.cs +++ b/src/Http/Http.Results/test/ProblemResultTests.cs @@ -59,6 +59,7 @@ public async Task ExecuteAsync_UsesDefaults_ForValidationProblemDetails() // Act await result.ExecuteAsync(httpContext); + // Assert Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); stream.Position = 0;