serialization-reviewlisted
Install: claude install-skill Sarmkadan/dotnet-senior-skills
# Serialization Review (.NET)
## One options instance, defined once
`JsonSerializerOptions` caches type metadata; a new instance per call rebuilds it every time - a real, measured hot-path cost. Define the codebase's options once (static readonly, or via `ConfigureHttpJsonOptions`/`AddJsonOptions` for ASP.NET Core) and reference it everywhere:
```csharp
// WRONG: metadata cache rebuilt per call, and settings drift per call site
return JsonSerializer.Serialize(dto, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
// RIGHT
public static class Json { public static readonly JsonSerializerOptions Web = new(JsonSerializerDefaults.Web); }
return JsonSerializer.Serialize(dto, Json.Web);
```
Two call sites with different casing policies for the same contract is a bug factory - the review flag is `new JsonSerializerOptions` anywhere outside composition/static init.
## Contracts evolve; plan for it in review
- Unknown incoming properties are silently dropped by default - good for forward compatibility, bad for security (see mass-assignment in the security skill) and for typo detection on internal contracts. For messages between your own services, `UnmappedMemberHandling = Disallow` turns silent contract drift into a loud failure.
- Renaming a property is a breaking change for every stored document and in-flight message, not just live callers. Additive evolution only: add the new property, keep reading the old one, migrate, then remove - the expand/