From 17aa21dc259a1d988faef80a576ed3b2bd4efc1c Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Fri, 23 Jan 2015 15:39:36 -0800 Subject: [PATCH] Added StatusCode property to OutputFormatterContext - Fixes issue #1809 - Added relevant tests --- .../ActionResults/ObjectResult.cs | 5 ++-- .../HttpNoContentOutputFormatter.cs | 2 +- .../Formatters/OutputFormatterContext.cs | 8 +++++ .../ActionResults/ObjectResultTests.cs | 30 +++++++++++++++++++ .../Formatters/NoContentFormatterTests.cs | 21 +++++++++++++ .../ActionResultTests.cs | 17 +++++++++++ .../ActionResultsVerificationController.cs | 7 +++++ 7 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs index 71dc28ffd4..0344300968 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs @@ -42,6 +42,7 @@ namespace Microsoft.AspNet.Mvc DeclaredType = DeclaredType, ActionContext = context, Object = Value, + StatusCode = StatusCode }; var selectedFormatter = SelectFormatter(formatterContext, formatters); @@ -52,9 +53,9 @@ namespace Microsoft.AspNet.Mvc return; } - if (StatusCode != null) + if (StatusCode.HasValue) { - context.HttpContext.Response.StatusCode = (int)StatusCode; + context.HttpContext.Response.StatusCode = StatusCode.Value; } OnFormatting(context); diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs index 2c0013918a..8d675d30c1 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs @@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc { var response = context.ActionContext.HttpContext.Response; response.ContentLength = 0; - response.StatusCode = 204; + response.StatusCode = context.StatusCode ?? 204; return Task.FromResult(true); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatterContext.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatterContext.cs index d7459e2d2a..ef139c378b 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatterContext.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatterContext.cs @@ -37,5 +37,13 @@ namespace Microsoft.AspNet.Mvc /// The content type which is chosen by the selected formatter. /// public MediaTypeHeaderValue SelectedContentType { get; set; } + + /// + /// Gets the status code that was previously set by the . + /// + /// + /// Null indicates no value set by the . + /// + public int? StatusCode { get; set; } } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs index 3caa8403df..aec28adec5 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs @@ -430,6 +430,36 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults Assert.Equal(input.Length, httpResponse.Object.Body.Length); } + [Fact] + public async Task ObjectResult_Execute_NullContent_SetsStatusCode() + { + // Arrange + var stream = new MemoryStream(); + var expectedStatusCode = 201; + var httpResponse = new Mock(); + httpResponse.SetupGet(r => r.Body).Returns(stream); + + var formatters = new IOutputFormatter[] + { + new HttpNoContentOutputFormatter(), + new StringOutputFormatter(), + new JsonOutputFormatter() + }; + var actionContext = CreateMockActionContext(formatters, + httpResponse.Object, + requestAcceptHeader: null, + requestContentType: null); + var result = new ObjectResult(null); + result.StatusCode = expectedStatusCode; + + // Act + await result.ExecuteResultAsync(actionContext); + + // Assert + httpResponse.VerifySet(r => r.StatusCode = expectedStatusCode); + Assert.Equal(0, httpResponse.Object.Body.Length); + } + [Fact] public async Task ObjectResult_Execute_CallsJsonResult_SetsContent() { diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs index 94077e45ed..50adfb3b11 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs @@ -127,5 +127,26 @@ namespace Microsoft.AspNet.Mvc.Test // Assert Assert.Equal(204, defaultHttpContext.Response.StatusCode); } + + [Fact] + public async Task WriteAsync_ContextStatusCodeSet_WritesSameStatusCode() + { + // Arrange + var defaultHttpContext = new DefaultHttpContext(); + var formatterContext = new OutputFormatterContext() + { + Object = null, + ActionContext = new ActionContext(defaultHttpContext, new RouteData(), new ActionDescriptor()), + StatusCode = 201 + }; + + var formatter = new HttpNoContentOutputFormatter(); + + // Act + await formatter.WriteAsync(formatterContext); + + // Assert + Assert.Equal(201, defaultHttpContext.Response.StatusCode); + } } } diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/ActionResultTests.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/ActionResultTests.cs index a34b9e4702..588f1d043c 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/ActionResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/ActionResultTests.cs @@ -307,5 +307,22 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests Assert.Equal("us-ascii", response.Content.Headers.ContentType.CharSet); Assert.Equal("content", await response.Content.ReadAsStringAsync()); } + + [Fact] + public async Task ObjectResult_WithStatusCodeAndNoContent_SetsSameStatusCode() + { + // Arrange + var server = TestServer.Create(_provider, _app); + var client = server.CreateClient(); + var request = new HttpRequestMessage( + HttpMethod.Get, + "http://localhost/ActionResultsVerification/GetObjectResultWithNoContent"); + + // Act + var response = await client.SendAsync(request); + + // Assert + Assert.Equal(HttpStatusCode.Created, response.StatusCode); + } } } \ No newline at end of file diff --git a/test/WebSites/ActionResultsWebSite/Controllers/ActionResultsVerificationController.cs b/test/WebSites/ActionResultsWebSite/Controllers/ActionResultsVerificationController.cs index 1073799b7c..7337d4a5b9 100644 --- a/test/WebSites/ActionResultsWebSite/Controllers/ActionResultsVerificationController.cs +++ b/test/WebSites/ActionResultsWebSite/Controllers/ActionResultsVerificationController.cs @@ -77,6 +77,13 @@ namespace ActionResultsWebSite return Content("content", "application/json", Encoding.ASCII); } + public IActionResult GetObjectResultWithNoContent() + { + var result = new ObjectResult(null); + result.StatusCode = 201; + return result; + } + public DummyClass GetDummy(int id) { return CreateDummy();