The Error
Your API throws when posting JSON:
System.Text.Json.JsonException: The JSON value could not be converted to System.Int32. Path: $.userId
Or: Each parameter in the deserialization constructor must bind to an object property
Quick Fix - 2 Minutes
.NET 8's System.Text.Json is stricter. Most errors are from 3 causes:
1. Type mismatch - sending string for int:
// You send this
{ "userId": "123" }
// C# expects this
public int UserId { get; set; } // CRASH
Fix: Send number or use JsonNumberHandling.AllowReadingFromString
2. Missing constructor parameters:
// This breaks in.NET 8
public class UserDto
{
public UserDto(string name) { Name = name; }
public string Name { get; }
public int Age { get; set; } // No way to set Age
}
Fix: Add [JsonConstructor] or add setters to all properties
3. Case sensitivity:
{ "userId": 123 }
public int UserID { get; set; } // Note the capital D - CRASH
Fix: Use [JsonPropertyName("userId")] or set PropertyNameCaseInsensitive = true
Why This Happens in.NET 8
Microsoft made System.Text.Json the default and removed Newtonsoft.Json. The new serializer is:
- Case-sensitive by default -
userId!=UserId - Strict about constructors - All constructor params must match JSON properties
- No string-to-number coercion -
"123"won't becomeint 123
Step-by-Step: Global Fix
Add this to Program.cs to make it behave like old Newtonsoft:
builder.Services.Configure<JsonOptions>(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString;
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
Common Scenarios
- Frontend sends strings: JavaScript
input.valueis always string. UseNumber()or the option above - Immutable records:
public record User(string Name, int Age);works. Custom classes need[JsonConstructor] - Enums as strings:
"Status": "Active"fails forenum Status. AddJsonStringEnumConverter - Dates:
"2026-06-04"fails forDateTime. Use ISO 8601:"2026-06-04T00:00:00Z"
Best Practice for.NET 8
1. Use records for DTOs: They auto-generate constructors that JSON understands
public record CreateUserRequest(string Name, int Age);
2. Be explicit with attributes when names differ:
public class UserDto
{
[JsonPropertyName("user_id")]
public int UserId { get; set; }
}
No comments yet. Be the first to share your thoughts!