# json-context-validator > Validates that all `JsonSerializer` usage is AOT-compatible by checking for proper `JsonSerializerContext` usage. - Author: Claude - Repository: psklarkins/claude-tools - Version: 20260108102420 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/psklarkins/claude-tools - Web: https://mule.run/skillshub/@@psklarkins/claude-tools~json-context-validator:20260108102420 --- # JSON Context Validator Skill Validates that all `JsonSerializer` usage is AOT-compatible by checking for proper `JsonSerializerContext` usage. ## When to Use This Skill - Before migrating to Native AOT - After adding new types that need JSON serialization - When you get IL20xx warnings about JSON during AOT publish - To audit JSON serialization patterns in existing code ## What This Skill Does 1. **Finds JsonSerializerContext classes** with `[JsonSerializable]` attributes 2. **Lists registered types** that are properly configured for AOT 3. **Detects unsafe usages** of `JsonSerializer` without context 4. **Identifies missing types** that are serialized but not registered ## Usage ```bash # Validate entire solution json-context-validator # Validate specific project json-context-validator --project SiemAgent.Core # Validate files matching pattern json-context-validator --file Client.cs # Show help json-context-validator --help ``` ## Example Output ``` === JSON CONTEXT ISSUES FOUND === Files analyzed: 45 === DISCOVERED CONTEXTS === SiemAgent.Models.SiemJsonContext File: src/SiemAgent.Models/SiemJsonContext.cs Types: - SiemEvent - EventBatch Registered types (2): [OK] SiemEvent [OK] EventBatch === MISSING TYPES (1) === These types are serialized but not registered in any context: [MISSING] HealthStatus Fix: Add [JsonSerializable(typeof(HealthStatus))] to your context === UNSAFE USAGES (2) === [EventBatch] src/Client/SiemClient.cs:45 Code: JsonSerializer.Serialize(batch) JsonSerializer.Serialize() called without source-generated context Fix: Use JsonSerializer.Serialize(value, SiemJsonContext.Default.EventBatch) ``` ## Creating a JsonSerializerContext ```csharp using System.Text.Json.Serialization; namespace MyApp; // Create a partial class with [JsonSerializable] for each type [JsonSerializable(typeof(SiemEvent))] [JsonSerializable(typeof(EventBatch))] [JsonSerializable(typeof(HealthStatus))] [JsonSerializable(typeof(List))] // Include collection types too! public partial class MyJsonContext : JsonSerializerContext { } ``` ## Fixing Unsafe Usages ### Before (Reflection-based) ```csharp // Uses reflection - NOT AOT compatible var json = JsonSerializer.Serialize(myObject); var obj = JsonSerializer.Deserialize(json); ``` ### After (Source-Generated) ```csharp // Uses source-generated serializers - AOT compatible var json = JsonSerializer.Serialize(myObject, MyJsonContext.Default.MyType); var obj = JsonSerializer.Deserialize(json, MyJsonContext.Default.MyType); ``` ## Common Issues ### Collection Types Don't forget to register collection types: ```csharp [JsonSerializable(typeof(List))] // Register List [JsonSerializable(typeof(Dictionary))] // Register dictionaries ``` ### Nested Types Register all types in object graphs: ```csharp [JsonSerializable(typeof(EventBatch))] [JsonSerializable(typeof(SiemEvent))] // Also register nested type [JsonSerializable(typeof(EventMetadata))] // And its nested types ``` ### Options Types If using custom `JsonSerializerOptions`, consider creating typed options: ```csharp [JsonSourceGenerationOptions( WriteIndented = true, PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] [JsonSerializable(typeof(MyType))] public partial class MyJsonContext : JsonSerializerContext { } ``` ## Integration with Other Skills **Recommended workflow:** 1. `aot-analyzer` - Find all AOT issues (including JSON) 2. `json-context-validator` - Focus specifically on JSON issues 3. `code-editor` - Fix issues 4. `dotnet publish -r win-x64 /p:PublishAot=true` - Verify ## Notes - Analysis is syntax-based (fast, no compilation required) - Some complex patterns may not be detected (e.g., dynamic type resolution) - Always test with actual AOT compilation after making changes - Generic types need explicit registration (`List`, `Dictionary`)