What's wrong
SchemaDataValidator.ValidateObject (Schema/Models/SchemaDataValidator.cs:176-196) handles member names inconsistently:
TryGetMemberProperty (L209-221) finds a member case-insensitively. Its doc comment says it accepts "the casing the serializer would have written".
accountedFor is a default HashSet<string> (ordinal comparison) filled with member.Name.
- The unknown-property loop (L191-196) then warns about every property name not in
accountedFor. That check is case-sensitive.
Failure scenario
Class Player has members Id and Name. The data is {"id": 1, "name": "x"}, which is what System.Text.Json writes with camelCase naming.
- Both members are found and validated.
- The validator then also warns
Class 'Player' has no member 'id' and … no member 'name'.
Every member of every object in a camelCase data file produces a false warning, which buries any real ones.
Suggested fix
Record the property name that actually matched: have TryGetMemberProperty return it and add that to accountedFor. Alternatively, construct accountedFor with StringComparer.OrdinalIgnoreCase.
Acceptance criteria
- Validating
{"id":1} against a class with member Id produces no issues.
- A genuinely unknown property (
{"Id":1,"extra":2}) still produces the warning.
- Tests cover both.
What's wrong
SchemaDataValidator.ValidateObject(Schema/Models/SchemaDataValidator.cs:176-196) handles member names inconsistently:TryGetMemberProperty(L209-221) finds a member case-insensitively. Its doc comment says it accepts "the casing the serializer would have written".accountedForis a defaultHashSet<string>(ordinal comparison) filled withmember.Name.accountedFor. That check is case-sensitive.Failure scenario
Class
Playerhas membersIdandName. The data is{"id": 1, "name": "x"}, which is whatSystem.Text.Jsonwrites with camelCase naming.Class 'Player' has no member 'id'and… no member 'name'.Every member of every object in a camelCase data file produces a false warning, which buries any real ones.
Suggested fix
Record the property name that actually matched: have
TryGetMemberPropertyreturn it and add that toaccountedFor. Alternatively, constructaccountedForwithStringComparer.OrdinalIgnoreCase.Acceptance criteria
{"id":1}against a class with memberIdproduces no issues.{"Id":1,"extra":2}) still produces the warning.