JsonSerializer.Deserialize fails

You can also read this microsoft documentation JSON Serialization, for the configuration you can use the following:

JsonSerializerOptions _jsonOptions = new(JsonSerializerDefaults.Web);
var serialized = JsonSerializer.Serialize(data, _jsonOptions);
var deserialized = JsonSerializer.Deserialize<TEntity>(serialized , _jsonOptions);

JsonSerializerDefaults.Web it is a predefined enum setting like "camelCase value", "case-insensitive property names", etc, check this JsonSerializerDefaults.? , if you want to customize you would check the documentation again here

Thanks to mr5 who suggested it was a casing issue via chat.

Changing the string to use TitleCase ("Id") solves the issue.

I was in the process of submitting a ticket, and one of the possibly related issues comments lead me to another issue, which lead to the documentation, which has a solution

var options = new JsonSerializerOptions();
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;

Using the options, solves the problem...

string str = "{\"id\": " + id + "}";
var options = new JsonSerializerOptions();
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
var u = JsonSerializer.Deserialize<User>(str, options);

Leaving this all up in case it helps someone else.

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 to true:

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.

(If the difference is entirely due to camel casing and not more general differences in case, you can instead configure the serializer to use camel case as shown in this answer by t.j..)

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 {
    public int Id { get; set; }

Demo fiddle #2 here.