JSON value could not be converted to System.String in C#
By FoxLearn 3/13/2025 2:50:08 AM 33
System.Text.Json.JsonException: The JSON value could not be converted to System.Int32. Path: $.Age | LineNumber: 0 | BytePositionInLine: 1.
This error occurs when the framework tries to deserialize a JSON value into an integer (System.Int32
), but the actual value might not match the expected type. You might be using an integer parameter with [FromBody]
, or the model you are binding has an integer property that maps to a nested JSON object.
To solve this, you have two options:
- Use
JsonElement
for flexible type handling. - Manually deserialize the request body to the correct type.
I'll walk you through examples for both solutions below.
Option 1 - Use JsonElement
Instead of int
Instead of binding the JSON value directly to an integer property, you can use JsonElement
. This allows you to inspect the raw JSON content and process it more flexibly.
using System.Text.Json; [HttpPost()] public IActionResult Post([FromBody] JsonElement jsonElement) { // Access a specific property _logger.LogInformation($"Age={jsonElement.GetProperty("Age")}"); return Ok(); }
In this example, the JsonElement
lets you check properties, and you can also manually convert them into the right type if necessary. For instance:
if (jsonElement.TryGetProperty("Age", out JsonElement ageElement) && ageElement.ValueKind == JsonValueKind.Number) { int age = ageElement.GetInt32(); }
Here, JsonElement
gives you the flexibility to handle different kinds of data without directly binding to a specific type.
Option 2 - Manually Deserialize the JSON Request Body
If you need to handle a dynamic request body, especially when the type is determined at runtime (e.g., based on a header), you can manually deserialize the request body. This method is useful if you have a "type discriminator" in the request to decide the correct model.
using System.Text.Json; [HttpPost()] public async Task<IActionResult> Post([FromHeader] string type) { if (type == "User") { User user = await JsonSerializer.DeserializeAsync<User>(Request.Body); _logger.LogInformation($"Received user with name: {user.Name}"); } return Ok(); }
In this case, you’re using DeserializeAsync()
to asynchronously read the request body and convert it to the appropriate type based on the value of the type
header. Note that DeserializeAsync()
is necessary because you can’t perform synchronous I/O operations by default.
This approach allows you to handle requests with dynamic or varying structures, especially when the type of the content isn't known until runtime.
- How to batch read with Threading.ChannelReader in C#
- How to ignore JSON deserialization errors in C#
- JsonException: A possible object cycle was detected
- Calling ‘BuildServiceProvider’ from application code results in an additional copy of singleton services being created
- How to use Newtonsoft in ASP.NET Core
- How to use Polly In C#
- Global exception event handlers in C#
- How to Add or overwrite a value in ConcurrentDictionary in C#