Use ProblemDetails.Status to configure ObjectResult.StatusCode (#17565)

This was missed when fixing https://github.com/aspnet/AspNetCore/issues/14663.
This commit is contained in:
Pranav K 2019-12-04 11:18:15 -08:00 committed by GitHub
parent bd7c89aa20
commit 00846a232c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 6 deletions

View File

@ -42,7 +42,10 @@ namespace Microsoft.Extensions.DependencyInjection
}
else
{
result = new ObjectResult(problemDetails);
result = new ObjectResult(problemDetails)
{
StatusCode = problemDetails.Status,
};
}
result.ContentTypes.Add("application/problem+json");
result.ContentTypes.Add("application/problem+xml");

View File

@ -54,14 +54,21 @@ namespace Microsoft.AspNetCore.Mvc
throw new ArgumentNullException(nameof(context));
}
if (Value is ProblemDetails details)
{
if (details.Status != null && StatusCode == null)
{
StatusCode = details.Status;
}
else if (details.Status == null && StatusCode != null)
{
details.Status = StatusCode;
}
}
if (StatusCode.HasValue)
{
context.HttpContext.Response.StatusCode = StatusCode.Value;
if (Value is ProblemDetails details && !details.Status.HasValue)
{
details.Status = StatusCode.Value;
}
}
}
}

View File

@ -7,6 +7,8 @@ using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Moq;
using Xunit;
namespace Microsoft.Extensions.DependencyInjection
@ -70,6 +72,29 @@ namespace Microsoft.Extensions.DependencyInjection
Assert.Equal(link, problemDetails.Type);
}
[Fact]
public void ProblemDetailsInvalidModelStateResponse_UsesProblemDetailsFactory()
{
// Arrange
var actionContext = GetActionContext();
var factory = Mock.Of<ProblemDetailsFactory>(m => m.CreateValidationProblemDetails(It.IsAny<HttpContext>(), It.IsAny<ModelStateDictionary>(), null, null, null, null, null) == new ValidationProblemDetails
{
Status = 422,
});
// Act
var result = ApiBehaviorOptionsSetup.ProblemDetailsInvalidModelStateResponse(factory, actionContext);
// Assert
var objectResult = Assert.IsType<ObjectResult>(result);
Assert.Equal(422, objectResult.StatusCode);
Assert.Equal(new[] { "application/problem+json", "application/problem+xml" }, objectResult.ContentTypes.OrderBy(c => c));
var problemDetails = Assert.IsType<ValidationProblemDetails>(objectResult.Value);
Assert.Equal(422, problemDetails.Status);
Assert.Equal("One or more validation errors occurred.", problemDetails.Title);
}
[Fact]
public void ProblemDetailsInvalidModelStateResponse_SetsTraceId()
{

View File

@ -94,6 +94,68 @@ namespace Microsoft.AspNetCore.Mvc
Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value);
}
[Fact]
public async Task ObjectResult_ExecuteResultAsync_GetsStatusCodeFromProblemDetails()
{
// Arrange
var details = new ProblemDetails { Status = StatusCodes.Status413RequestEntityTooLarge, };
var result = new ObjectResult(details)
{
Formatters = new FormatterCollection<IOutputFormatter>()
{
new NoOpOutputFormatter(),
},
};
var actionContext = new ActionContext()
{
HttpContext = new DefaultHttpContext()
{
RequestServices = CreateServices(),
}
};
// Act
await result.ExecuteResultAsync(actionContext);
// Assert
Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, details.Status.Value);
Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, result.StatusCode.Value);
Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, actionContext.HttpContext.Response.StatusCode);
}
[Fact]
public async Task ObjectResult_ExecuteResultAsync_ResultAndProblemDetailsHaveStatusCodes()
{
// Arrange
var details = new ProblemDetails { Status = StatusCodes.Status422UnprocessableEntity, };
var result = new BadRequestObjectResult(details)
{
Formatters = new FormatterCollection<IOutputFormatter>()
{
new NoOpOutputFormatter(),
},
};
var actionContext = new ActionContext()
{
HttpContext = new DefaultHttpContext()
{
RequestServices = CreateServices(),
}
};
// Act
await result.ExecuteResultAsync(actionContext);
// Assert
Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value);
Assert.Equal(StatusCodes.Status400BadRequest, result.StatusCode.Value);
Assert.Equal(StatusCodes.Status400BadRequest, actionContext.HttpContext.Response.StatusCode);
}
private static IServiceProvider CreateServices()
{
var services = new ServiceCollection();