diff --git a/aspnetcore/web-api/action-return-types.md b/aspnetcore/web-api/action-return-types.md index 0c1bf2e643..9af1feda5c 100644 --- a/aspnetcore/web-api/action-return-types.md +++ b/aspnetcore/web-api/action-return-types.md @@ -4,7 +4,7 @@ author: scottaddie description: Learn about using the various controller action method return types in an ASP.NET Core Web API. ms.author: scaddie ms.custom: mvc -ms.date: 07/23/2018 +ms.date: 01/04/2019 uid: web-api/action-return-types --- # Controller action return types in ASP.NET Core Web API @@ -62,14 +62,19 @@ Consider the following asynchronous action in which there are two possible retur [!code-csharp[](../web-api/action-return-types/samples/WebApiSample.Api.Pre21/Controllers/ProductsController.cs?name=snippet_CreateAsync&highlight=8,13)] -In the preceding action, a 400 status code is returned when model validation fails and the [BadRequest](/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.badrequest) helper method is invoked. For example, the following model indicates that requests must provide the `Name` property and a value. Therefore, failure to provide a proper `Name` in the request causes model validation to fail. +In the preceding code: -[!code-csharp[](../web-api/action-return-types/samples/WebApiSample.DataAccess/Models/Product.cs?name=snippet_ProductClass&highlight=5-6)] +* A 400 status code ([BadRequest](xref:Microsoft.AspNetCore.Mvc.ControllerBase.BadRequest*)) is returned by the ASP.NET Core runtime when the product description contains "XYZ Widget". +* A 201 status code is generated by the [CreatedAtAction](xref:Microsoft.AspNetCore.Mvc.ControllerBase.CreatedAtAction*) method when a product is created. In this code path, the `Product` object is returned. -The preceding action's other known return code is a 201, which is generated by the [CreatedAtAction](/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.createdataction) helper method. In this path, the `Product` object is returned. +For example, the following model indicates that requests must include the `Name` and `Description` properties. Therefore, failure to provide `Name` and `Description` in the request causes model validation to fail. + +[!code-csharp[](../web-api/action-return-types/samples/WebApiSample.DataAccess/Models/Product.cs?name=snippet_ProductClass&highlight=5-6,8-9)] ::: moniker range=">= aspnetcore-2.1" +If the [[ApiController]](xref:Microsoft.AspNetCore.Mvc.ApiControllerAttribute) attribute in ASP.NET Core 2.1 or later is applied, model validation errors result in a 400 status code. For more information, see [Automatic HTTP 400 responses](xref:web-api/index#automatic-http-400-responses). + ## ActionResult\ type ASP.NET Core 2.1 introduces the [ActionResult\](/dotnet/api/microsoft.aspnetcore.mvc.actionresult-1) return type for Web API controller actions. It enables you to return a type deriving from [ActionResult](/dotnet/api/microsoft.aspnetcore.mvc.actionresult) or return a [specific type](#specific-type). `ActionResult` offers the following benefits over the [IActionResult type](#iactionresult-type): @@ -108,7 +113,12 @@ Consider an asynchronous action in which there are two possible return types: [!code-csharp[](../web-api/action-return-types/samples/WebApiSample.Api.21/Controllers/ProductsController.cs?name=snippet_CreateAsync&highlight=8,13)] -If model validation fails, the [BadRequest](/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.badrequest#Microsoft_AspNetCore_Mvc_ControllerBase_BadRequest_Microsoft_AspNetCore_Mvc_ModelBinding_ModelStateDictionary_) method is invoked to return a 400 status code. The [ModelState](/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.modelstate) property containing the specific validation errors is passed to it. If model validation succeeds, the product is created in the database. A 201 status code is returned. +In the preceding code: + +* A 400 status code ([BadRequest](xref:Microsoft.AspNetCore.Mvc.ControllerBase.BadRequest*)) is returned by the ASP.NET Core runtime when: + * The [[ApiController]](xref:Microsoft.AspNetCore.Mvc.ApiControllerAttribute) attribute has been applied and model validation fails. + * The product description contains "XYZ Widget". +* A 201 status code is generated by the [CreatedAtAction](xref:Microsoft.AspNetCore.Mvc.ControllerBase.CreatedAtAction*) method when a product is created. In this code path, the `Product` object is returned. > [!TIP] > As of ASP.NET Core 2.1, action parameter binding source inference is enabled when a controller class is decorated with the `[ApiController]` attribute. Complex type parameters are automatically bound using the request body. Consequently, the preceding action's `product` parameter isn't explicitly annotated with the [[FromBody]](/dotnet/api/microsoft.aspnetcore.mvc.frombodyattribute) attribute. diff --git a/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.21/Controllers/ProductsController.cs b/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.21/Controllers/ProductsController.cs index ddac3e29c7..99e0371dd4 100644 --- a/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.21/Controllers/ProductsController.cs +++ b/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.21/Controllers/ProductsController.cs @@ -46,9 +46,9 @@ namespace WebApiSample.Controllers [ProducesResponseType(400)] public async Task> CreateAsync(Product product) { - if (!ModelState.IsValid) + if (product.Description.Contains("XYZ Widget")) { - return BadRequest(ModelState); + return BadRequest(); } await _repository.AddProductAsync(product); diff --git a/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.Pre21/Controllers/ProductsController.cs b/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.Pre21/Controllers/ProductsController.cs index 91b40b89de..1cfe052197 100644 --- a/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.Pre21/Controllers/ProductsController.cs +++ b/aspnetcore/web-api/action-return-types/samples/WebApiSample.Api.Pre21/Controllers/ProductsController.cs @@ -45,9 +45,9 @@ namespace WebApiSample.Api.Pre21.Controllers [ProducesResponseType(400)] public async Task CreateAsync([FromBody] Product product) { - if (!ModelState.IsValid) + if (product.Description.Contains("XYZ Widget")) { - return BadRequest(ModelState); + return BadRequest(); } await _repository.AddProductAsync(product); diff --git a/aspnetcore/web-api/action-return-types/samples/WebApiSample.DataAccess/Models/Product.cs b/aspnetcore/web-api/action-return-types/samples/WebApiSample.DataAccess/Models/Product.cs index fecc8ab522..26c1d672e0 100644 --- a/aspnetcore/web-api/action-return-types/samples/WebApiSample.DataAccess/Models/Product.cs +++ b/aspnetcore/web-api/action-return-types/samples/WebApiSample.DataAccess/Models/Product.cs @@ -10,6 +10,7 @@ namespace WebApiSample.DataAccess.Models [Required] public string Name { get; set; } + [Required] public string Description { get; set; } } #endregion