Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ApiController does not always return data in BadRequest

I am using an ASP.NET Core 2.2 ApiController and I have the following:

[ApiController]
public class PostController : Controller {
  [HttpGet("posts")]
  public async Task<IActionResult> Get() {
    return BadRequest();
  }
}

In this case I get the following response:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "traceId": "0HLMFSL0C7SKB:00000001"
}

But if I return some data as follows:

[ApiController]
public class PostController : Controller {
  [HttpGet("posts")]
  public async Task<IActionResult> Get() {
    List<String> errors = new List<String> { "Code is invalid" };
    return BadRequest(new { errors = errors });
  }
}

I get the following:

{
  "errors": ["Code is invalid"]
}

Why does ApiController adds type, title, status and traceId when no content is returned?

I would like the responses to be always similar like:

{
  "errors": ["Code is invalid"],
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "traceId": "0HLMFSL0C7SKB:00000001"
}
like image 837
Miguel Moura Avatar asked May 03 '19 16:05

Miguel Moura


2 Answers

Instead of returning a BadRequest() result you just need to return a ValidationProblem() result instead. This will give you the ProblemDetails object response with the current ModelState errors populated.

like image 118
Codemunkie Avatar answered Nov 15 '22 07:11

Codemunkie


The default ControllerBase.BadRequest() response content is because you have the [ApiController] attribute applied to your controller. This is documented online:

When the compatibility version is 2.2 or later, MVC transforms an error result (a result with status code 400 or higher) to a result with ProblemDetails. The ProblemDetails type is based on the RFC 7807 specification for providing machine-readable error details in an HTTP response.

This includes the type, title, status and traceId values.

If you do not have [ApiController] applied then ControllerBase.BadRequest() will return an empty response with HTTP 400 status code.

All overloads of ControllerBase.BadRequest that accept a value or model response object will serialize and return that instead of using the ApiController default response.

like image 10
Dai Avatar answered Nov 15 '22 07:11

Dai