How it works
By default, System.Text.Json can ignore object properties that do not map to model members. That behavior supports some forms of forward compatibility, but it can also hide misspellings or configuration mistakes. The sample first accepts the known Count member while ignoring the unknown Extra member.
The second configuration sets UnmappedMemberHandling to Disallow. The same input now produces JsonException because Extra has no member in Counter. This option is available in the .NET version used by the lesson and makes a strict object-shape boundary explicit instead of relying on a later surprising default.
Strictness is a compatibility policy. A client consuming a server that intentionally adds optional fields may need to ignore unknown members. A local configuration file where every spelling is user-controlled may benefit from rejecting them. Neither choice is universally correct; choose according to who owns the schema and how versions evolve.
Rejecting unknown members does not validate the business meaning of known members. A negative Count still maps to the right property and may require a separate domain check. Structural acceptance, presence requirements, null rules, and numeric constraints are distinct layers of validation even when they all apply to the same payload.
Practice by removing Extra, misspelling Count, and adding a second known optional property to the model. Compare the default and strict behavior for each input. Record which layer detects the error and make the resulting message useful without exposing unrelated internal details.
Finally, write down a versioning rule for an evolving payload. If new fields are permitted, specify how older readers behave; if they are forbidden, provide a clear upgrade path. Tests should cover both current valid input and realistic future or mistyped input, so changing serializer options cannot silently alter the application's compatibility contract.
A working example
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
const string json = """{"Count":3,"Extra":9}""";
Console.WriteLine(JsonSerializer.Deserialize<Counter>(json)!.Count);
var options = new JsonSerializerOptions { UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow };
try { JsonSerializer.Deserialize<Counter>(json, options); }
catch (JsonException) { Console.WriteLine("unknown rejected"); }
class Counter { public int Count { get; set; } }
Expected output
3 unknown rejected
Disallow unknown fields when that strictness is part of the input contract.