Description
This issue is related to this dotnet/runtime issue.
The examples below use a vanilla ASP.NET Core application with this controller:
namespace ApplicationName.Controllers
{
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
// This of course belongs to a different file and namespace:
public class Model
{
public Guid Id { get; set; }
public int Integer { get; set; }
public string String { get; set; }
}
[Produces("application/json")]
[Consumes("application/json")]
[Route("test")]
[ApiController]
public class Controller : ControllerBase
{
[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] Model model)
{
return Ok(model);
}
}
}
In each example below, the body for a POST
request is listed first. Then comes the response when using Newtonsoft.JSON
for doing the model binding, and then the response when using System.Text.Json
.
Example 1:
{
"id": "00000000-0000-0000-0000-00000000000x",
"integer": 2,
"string": "2"
}
Response using Newtonsoft.JSON
:
{
"errors": {
"id": [
"Error converting value \"00000000-0000-0000-0000-00000000000x\" to type 'System.Guid'. Path 'id', line 2, position 48."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|ac238c1a-4b2c24d7c287f27d."
}
Response using System.Text.Json
:
{
"errors": {
"$": [
"The JSON value could not be converted to ApplicationName.Controllers.Model. Path: $ | LineNumber: 1 | BytePositionInLine: 48."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"detail": null,
"instance": null,
"traceId": "|29c80116-4896648215ca6161."
}
Example 2:
{
"id": "00000000-0000-0000-0000-00000000000a",
"integer": 2x,
"string": "2"
}
Response using Newtonsoft.JSON
:
{
"errors": {
"integer": [
"Input string '2x' is not a valid integer. Path 'integer', line 3, position 17."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|ac238c1b-4b2c24d7c287f27d."
}
Response using System.Text.Json
:
{
"errors": {
"$": [
"'x' is an invalid end of a number. Expected a delimiter. Path: $ | LineNumber: 2 | BytePositionInLine: 16."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"detail": null,
"instance": null,
"traceId": "|29c80117-4896648215ca6161."
}
Example 3:
{
"id": "00000000-0000-0000-0000-00000000000a",
"integer": 2,
"string": 2 x
}
Response using Newtonsoft.JSON
:
{
"errors": {
"string": [
"After parsing a value an unexpected character was encountered: x. Path 'string', line 4, position 16."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|ac238c1d-4b2c24d7c287f27d."
}
Response using System.Text.Json
:
{
"errors": {
"$": [
"The JSON value could not be converted to ApplicationName.Controllers.Model. Path: $ | LineNumber: 3 | BytePositionInLine: 15."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"detail": null,
"instance": null,
"traceId": "|a88bc7ad-44774eaf80acd428."
}
Example 4:
{
"id": "00000000-0000-0000-0000-00000000000a",
"integer": 2,
"string": 2
}
Response using Newtonsoft.JSON
(no error in this case due to lenient parsing):
{
"id": "00000000-0000-0000-0000-00000000000a",
"integer": 2,
"string": "2"
}
Response using System.Text.Json
(strict is better, but this could still be improved):
{
"errors": {
"$": [
"The JSON value could not be converted to ApplicationName.Controllers.Model. Path: $ | LineNumber: 3 | BytePositionInLine: 15."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"detail": null,
"instance": null,
"traceId": "|29c80118-4896648215ca6161."
}
The responses when using System.Text.Json
consistently makes it harder for the end user to figure out what is wrong. It would be great if the validation errors when using System.Text.Json
would be of the same quality as when using Newtonsoft.Json
.