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:

Terminal window
dotnet new console -n StrictJsonDemo -f net10.0
cd StrictJsonDemo

Replace 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:

Terminal window
dotnet run

The 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); // False
Console.WriteLine(options.UnmappedMemberHandling); // Disallow
Console.WriteLine(options.RespectNullableAnnotations); // True
Console.WriteLine(options.RespectRequiredConstructorParameters); // True
Console.WriteLine(options.PropertyNameCaseInsensitive); // False

You 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.