Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Add UnprocessableEntityResult, UnprocessableEntityObjectResult and ControllerBase.UnprocessableEntity methods #6851

Merged
merged 4 commits into from
Sep 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,7 @@ public virtual BadRequestResult BadRequest()
/// <summary>
/// Creates an <see cref="BadRequestObjectResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <param name="error">An error object to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestObjectResult BadRequest(object error)
Expand All @@ -1486,6 +1487,7 @@ public virtual BadRequestObjectResult BadRequest(object error)
/// <summary>
/// Creates an <see cref="BadRequestObjectResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <param name="modelState">The model state dictionary containing errors to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestObjectResult BadRequest(ModelStateDictionary modelState)
Expand All @@ -1498,6 +1500,43 @@ public virtual BadRequestObjectResult BadRequest(ModelStateDictionary modelState
return new BadRequestObjectResult(modelState);
}

/// <summary>
/// Creates an <see cref="UnprocessableEntityResult"/> that produces a <see cref="StatusCodes.Status422UnprocessableEntity"/> response.
/// </summary>
/// <returns>The created <see cref="UnprocessableEntityResult"/> for the response.</returns>
[NonAction]
public virtual UnprocessableEntityResult UnprocessableEntity()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public virtual UnprocessableEntityResult UnprocessableEntity() => new UnprocessableEntityResult() for 💯 points

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many other methods like this in the same class, it it worth the inconsistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's leave this for #6864 😄

{
return new UnprocessableEntityResult();
}

/// <summary>
/// Creates an <see cref="UnprocessableEntityObjectResult"/> that produces a <see cref="StatusCodes.Status422UnprocessableEntity"/> response.
/// </summary>
/// <param name="error">An error object to be returned to the client.</param>
/// <returns>The created <see cref="UnprocessableEntityObjectResult"/> for the response.</returns>
[NonAction]
public virtual UnprocessableEntityObjectResult UnprocessableEntity(object error)
{
return new UnprocessableEntityObjectResult(error);
}

/// <summary>
/// Creates an <see cref="UnprocessableEntityObjectResult"/> that produces a <see cref="StatusCodes.Status422UnprocessableEntity"/> response.
/// </summary>
/// <param name="modelState">The model state dictionary containing errors to be returned to the client.</param>
/// <returns>The created <see cref="UnprocessableEntityObjectResult"/> for the response.</returns>
[NonAction]
public virtual UnprocessableEntityObjectResult UnprocessableEntity(ModelStateDictionary modelState)
{
if (modelState == null)
{
throw new ArgumentNullException(nameof(modelState));
}

return new UnprocessableEntityObjectResult(modelState);
}

/// <summary>
/// Creates an <see cref="BadRequestObjectResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// An <see cref="ObjectResult"/> that when executed will produce a Unprocessable Entity (422) response.
/// </summary>
public class UnprocessableEntityObjectResult : ObjectResult
{
/// <summary>
/// Creates a new <see cref="UnprocessableEntityObjectResult"/> instance.
/// </summary>
/// <param name="modelState"><see cref="ModelStateDictionary"/> containing the validation errors.</param>
public UnprocessableEntityObjectResult(ModelStateDictionary modelState)
: this(new SerializableError(modelState))
{
}

/// <summary>
/// Creates a new <see cref="UnprocessableEntityObjectResult"/> instance.
/// </summary>
/// <param name="error">Contains errors to be returned to the client.</param>
public UnprocessableEntityObjectResult(object error)
: base(error)
{
StatusCode = StatusCodes.Status422UnprocessableEntity;
}
}
}
22 changes: 22 additions & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/UnprocessableEntityResult.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// A <see cref="StatusCodeResult"/> that when
/// executed will produce a Unprocessable Entity (422) response.
/// </summary>
public class UnprocessableEntityResult : StatusCodeResult
{
/// <summary>
/// Creates a new <see cref="UnprocessableEntityResult"/> instance.
/// </summary>
public UnprocessableEntityResult()
: base(StatusCodes.Status422UnprocessableEntity)
{
}
}
}
46 changes: 46 additions & 0 deletions test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,52 @@ public void BadRequest_SetsStatusCodeAndValue_ModelState()
Assert.Empty(errors);
}

[Fact]
public void UnprocessableEntity_SetsStatusCode()
{
// Arrange
var controller = new TestableController();

// Act
var result = controller.UnprocessableEntity();

// Assert
Assert.IsType<UnprocessableEntityResult>(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<UnprocessableEntityObjectResult>(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<UnprocessableEntityObjectResult>(result);
Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode);
var errors = Assert.IsType<SerializableError>(result.Value);
Assert.Empty(errors);
}

[Theory]
[MemberData(nameof(PublicNormalMethodsFromControllerBase))]
public void NonActionAttribute_IsOnEveryPublicNormalMethodFromControllerBase(MethodInfo method)
Expand Down
Original file line number Diff line number Diff line change
@@ -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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe toss in an error in to the MSD so we know it's the type that's being serialized.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no serialization in the test, and taht's fine. We don't need to overthink it


// Assert
Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode);
var errors = Assert.IsType<SerializableError>(result.Value);
Assert.Empty(errors);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}