From 97fab8711af62987cc554e36cc8f2900184d483a Mon Sep 17 00:00:00 2001 From: Kristian Hellang Date: Fri, 22 Sep 2017 18:27:29 +0200 Subject: [PATCH] Add UnprocessableEntityResult, UnprocessableEntityObjectResult and ControllerBase.UnprocessableEntity methods (#6851) * Added UnprocessableEntityResult * Added UnprocessableEntityObjectResult * Added UnprocessableEntity overloads to ControllerBase Fixes https://github.com/aspnet/Mvc/issues/6795 --- .../ControllerBase.cs | 39 ++++++++++++++++ .../UnprocessableEntityObjectResult.cs | 33 +++++++++++++ .../UnprocessableEntityResult.cs | 22 +++++++++ .../ControllerBaseTest.cs | 46 +++++++++++++++++++ .../UnprocessableEntityObjectResultTests.cs | 36 +++++++++++++++ .../UnprocessableEntityResultTests.cs | 21 +++++++++ 6 files changed, 197 insertions(+) create mode 100644 src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityObjectResult.cs create mode 100644 src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityResult.cs create mode 100644 test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityObjectResultTests.cs create mode 100644 test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityResultTests.cs diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs b/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs index 0305f8e14e..ec3f58a6e8 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs @@ -1400,6 +1400,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// Creates an that produces a response. /// + /// An error object to be returned to the client. /// The created for the response. [NonAction] public virtual BadRequestObjectResult BadRequest(object error) @@ -1408,6 +1409,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// Creates an that produces a response. /// + /// The model state dictionary containing errors to be returned to the client. /// The created for the response. [NonAction] public virtual BadRequestObjectResult BadRequest(ModelStateDictionary modelState) @@ -1420,6 +1422,43 @@ namespace Microsoft.AspNetCore.Mvc return new BadRequestObjectResult(modelState); } + /// + /// Creates an that produces a response. + /// + /// The created for the response. + [NonAction] + public virtual UnprocessableEntityResult UnprocessableEntity() + { + return new UnprocessableEntityResult(); + } + + /// + /// Creates an that produces a response. + /// + /// An error object to be returned to the client. + /// The created for the response. + [NonAction] + public virtual UnprocessableEntityObjectResult UnprocessableEntity(object error) + { + return new UnprocessableEntityObjectResult(error); + } + + /// + /// Creates an that produces a response. + /// + /// The model state dictionary containing errors to be returned to the client. + /// The created for the response. + [NonAction] + public virtual UnprocessableEntityObjectResult UnprocessableEntity(ModelStateDictionary modelState) + { + if (modelState == null) + { + throw new ArgumentNullException(nameof(modelState)); + } + + return new UnprocessableEntityObjectResult(modelState); + } + /// /// Creates an that produces a response. /// diff --git a/src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityObjectResult.cs b/src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityObjectResult.cs new file mode 100644 index 0000000000..002d9d97af --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityObjectResult.cs @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace Microsoft.AspNetCore.Mvc +{ + /// + /// An that when executed will produce a Unprocessable Entity (422) response. + /// + public class UnprocessableEntityObjectResult : ObjectResult + { + /// + /// Creates a new instance. + /// + /// containing the validation errors. + public UnprocessableEntityObjectResult(ModelStateDictionary modelState) + : this(new SerializableError(modelState)) + { + } + + /// + /// Creates a new instance. + /// + /// Contains errors to be returned to the client. + public UnprocessableEntityObjectResult(object error) + : base(error) + { + StatusCode = StatusCodes.Status422UnprocessableEntity; + } + } +} diff --git a/src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityResult.cs b/src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityResult.cs new file mode 100644 index 0000000000..0851057499 --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityResult.cs @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNetCore.Mvc +{ + /// + /// A that when + /// executed will produce a Unprocessable Entity (422) response. + /// + public class UnprocessableEntityResult : StatusCodeResult + { + /// + /// Creates a new instance. + /// + public UnprocessableEntityResult() + : base(StatusCodes.Status422UnprocessableEntity) + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs index b2b9e5c339..c2f10b2fc0 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs @@ -1990,6 +1990,52 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test Assert.Empty(errors); } + [Fact] + public void UnprocessableEntity_SetsStatusCode() + { + // Arrange + var controller = new TestableController(); + + // Act + var result = controller.UnprocessableEntity(); + + // Assert + Assert.IsType(result); + Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); + } + + [Fact] + public void UnprocessableEntity_SetsStatusCodeAndValue_Object() + { + // Arrange + var controller = new TestableController(); + var obj = new object(); + + // Act + var result = controller.UnprocessableEntity(obj); + + // Assert + Assert.IsType(result); + Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); + Assert.Equal(obj, result.Value); + } + + [Fact] + public void UnprocessableEntity_SetsStatusCodeAndValue_ModelState() + { + // Arrange + var controller = new TestableController(); + + // Act + var result = controller.UnprocessableEntity(new ModelStateDictionary()); + + // Assert + Assert.IsType(result); + Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); + var errors = Assert.IsType(result.Value); + Assert.Empty(errors); + } + [Theory] [MemberData(nameof(PublicNormalMethodsFromControllerBase))] public void NonActionAttribute_IsOnEveryPublicNormalMethodFromControllerBase(MethodInfo method) diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityObjectResultTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityObjectResultTests.cs new file mode 100644 index 0000000000..7ab3fcfd9f --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityObjectResultTests.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc +{ + public class UnprocessableEntityObjectResultTests + { + [Fact] + public void UnprocessableEntityObjectResult_SetsStatusCodeAndValue() + { + // Arrange & Act + var obj = new object(); + var result = new UnprocessableEntityObjectResult(obj); + + // Assert + Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); + Assert.Equal(obj, result.Value); + } + + [Fact] + public void UnprocessableEntityObjectResult_ModelState_SetsStatusCodeAndValue() + { + // Arrange & Act + var result = new UnprocessableEntityObjectResult(new ModelStateDictionary()); + + // Assert + Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); + var errors = Assert.IsType(result.Value); + Assert.Empty(errors); + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityResultTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityResultTests.cs new file mode 100644 index 0000000000..b54f474154 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/UnprocessableEntityResultTests.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Http; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc +{ + public class UnprocessableEntityResultTests + { + [Fact] + public void UnprocessableEntityResult_InitializesStatusCode() + { + // Arrange & act + var result = new UnprocessableEntityResult(); + + // Assert + Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); + } + } +}