JSON from the outside world can get weird.
A payload can repeat the same property twice, slip in fields you never expected, or leave out a constructor value your code needs. The default System.Text.Json settings try to be friendly about most of that.
Sometimes friendly is the last thing you want.
.NET 10 adds JsonSerializerOptions.Strict, a ready-made set of options for treating your JSON contract like an actual contract.
Try It
Create a .NET 10 console app:
dotnet new console -n StrictJsonDemo -f net10.0cd StrictJsonDemoReplace Program.cs with this:
using System.Text.Json;
const string validJson = """{"Id":42,"Product":"Mechanical Keyboard"}""";
const string duplicateProperty = """{"Id":42,"Product":"Keyboard","Product":"Mystery Box"}""";
const string unknownProperty = """{"Id":42,"Product":"Keyboard","Coupon":"FREE-STUFF"}""";
Read("Valid", validJson);Read("Duplicate property", duplicateProperty);Read("Unknown property", unknownProperty);
static void Read(string label, string json){ try { var order = JsonSerializer.Deserialize<Order>( json, JsonSerializerOptions.Strict);
Console.WriteLine($"{label}: accepted {order}"); } catch (JsonException ex) { Console.WriteLine($"{label}: rejected"); Console.WriteLine($" {ex.Message}"); }}
public sealed record Order(int Id, string Product);Run it:
dotnet runThe valid payload works. The duplicate and unknown properties throw JsonException.
What Strict Mode Turns On
The preset combines several settings:
var options = JsonSerializerOptions.Strict;
Console.WriteLine(options.AllowDuplicateProperties); // FalseConsole.WriteLine(options.UnmappedMemberHandling); // DisallowConsole.WriteLine(options.RespectNullableAnnotations); // TrueConsole.WriteLine(options.RespectRequiredConstructorParameters); // TrueConsole.WriteLine(options.PropertyNameCaseInsensitive); // FalseYou can also clone the preset when you need to adjust another setting:
var options = new JsonSerializerOptions(JsonSerializerOptions.Strict){ WriteIndented = true};When Not to Use It
Strict mode is a great fit when you own both sides of an API or you need tight validation at a boundary.
It can be painful when you consume a third-party API that adds fields without warning. Rejecting every unknown property means a harmless upstream addition can break your integration. In that situation, choose the individual strict settings that protect you without making the contract brittle.
Key Takeaway
JsonSerializerOptions.Strict gives you a safer JSON baseline with one preset. It catches duplicate properties, unexpected fields, missing required constructor values, and nullability problems before questionable data wanders deeper into your app.