Why System.Text.Json Is More Strict Than You Expect
There I was, staring at my console, wondering why a perfectly good JSON blob was refusing to deserialize. I had recently swapped out Newtonsoft.Json
for the leaner, faster System.Text.Json
, excited to embrace a modern, built-in library. But then… nothing worked. No errors, no obvious hints. Just silent failure. It felt like JSON gaslighting.
The Problem
Coming from years of using Newtonsoft.Json
, I expected everything to “just work.” But as I quickly learned, System.Text.Json
is a stricter roommate. The most maddening issue? My JSON deserialization fails for no reason — or so I thought.
Turns out, the reasons were there. Just sneakier than I expected:
- Property name case sensitivity (yes, really)
- Missing parameterless constructors
- Lack of support for private setters
- No out-of-the-box support for many
Newtonsoft.Json
features I had taken for granted
The Solution
The first breakthrough came when I realized System.Text.Json
is case-sensitive by default. That meant "firstName"
in JSON wouldn’t match a FirstName
property in my C# class unless I added [JsonPropertyName("firstName")]
or enabled case-insensitive options.
Second, it expects a parameterless constructor unless you’re using constructor binding — and that also has its quirks. Unlike Newtonsoft, it doesn’t quietly skip over this; it just… fails.
So, I adjusted:
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
And made sure my classes either had parameterless constructors or used [JsonConstructor]
properly.
Deeper Explanation
System.Text.Json
was designed with performance and security in mind, so it avoids the magic Newtonsoft often performs behind the scenes. That’s great for predictable behavior and speed, but it also means you need to be more explicit.
Constructor binding in System.Text.Json
is also more rigid. Parameter names must match property names in the JSON exactly, or they won’t bind. That’s not a bug — it’s a “feature.”
Best Practices
- Always test your models with realistic JSON samples early
- Use
JsonSerializerOptions
wisely — especiallyPropertyNameCaseInsensitive
- Embrace
[JsonPropertyName]
to map property names explicitly - Avoid surprises by reading the System.Text.Json docs
Conclusion
If you’re switching from Newtonsoft.Json
, expect a little friction — but it’s worth it. Yes, my JSON deserialization fails for no reason… until I understood why. And now that I do, I actually appreciate the clarity that System.Text.Json
brings.
Just remember: strict doesn’t mean broken — it means you’re in charge.
Leave a Reply