Consider the code...
using System;
using System.Text.Json;
public class Program
{
public static void Main()
{
int id = 9;
string str = "{\"id\": " + id + "}";
var u = JsonSerializer.Deserialize<User>(str);
Console.WriteLine($"User ID: {u.Id}, Correct: {id == u.Id}"); // always 0/init/default value
}
}
public class User {
public int Id { get; set; }
}
Why isn't the data being deserialized properly into the User
object? I also verified the behavior via DotNetFiddle in case it was an issue local to my system. No exception is thrown.
My actual implementation is read from an [ApiController]
's [HttpPost]
action after I return Created("user", newUser)
. It is called in my MVC/Razor project via _httpClient.PostAsync
. I verified the values are correct when Created
is returned to the PostAsync
call, but no matter what, the value parsed from the response body contains only default values (the actual ID is a Guid
).
I initially thought it might have been an UTF8 related issue, as that is the encoding for the StringContent
I post to the ApiController
. UTF8 deserialization is referenced here, but I had trouble getting from the IO.Stream of the HttpContent
to a ReadOnlySpan
or Utf8JsonReader
.
I found this project while searching, which makes me think it should work as I expected.
Your problem is that System.Text.Json
is case-sensitive by default, so "id": 9
(all lowercase) is not mapped to the Id
property. From the docs:
Case-insensitive property matching
By default, deserialization looks for case-sensitive property name matches between JSON and the target object properties. To change that behavior, set
JsonSerializerOptions.PropertyNameCaseInsensitive
totrue
:Note: The web default is case-insensitive.
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, }; var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options);
So you need to do that also:
var u = JsonSerializer.Deserialize<User>(str, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Demo fiddle #1 here.
You can configure the option on startup in ASP.NET Core 3.0 as shown in How to set json serializer settings in asp.net core 3?:
services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});
Alternatively you could apply [JsonPropertyName("id")]
to your model:
public class User {
[JsonPropertyName("id")]
public int Id { get; set; }
}
Demo fiddle #2 here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With