# Dotnet Source Gen Json

> Configures System.Text.Json source generation for AOT-compatible JSON serialization. Also use when the user mentions "JSON source generator," "JsonSerializerContext," "JsonSerializable," "AOT JSON," "reflection-free JSON," or "System.Text.Json source gen." For polymorphic types, see dotnet-json-polymorphic. For full AOT analysis, see dotnet-aot-analysis.

- **Type:** Skill
- **Install:** `agentstack add skill-im5tu-claude-dotnet-source-gen-json`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Im5tu](https://agentstack.voostack.com/s/im5tu)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Im5tu](https://github.com/Im5tu)
- **Source:** https://github.com/Im5tu/claude/tree/main/skills/dotnet-source-gen-json
- **Website:** https://codewithstu.tv

## Install

```sh
agentstack add skill-im5tu-claude-dotnet-source-gen-json
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

Configure System.Text.Json source generation for AOT-compatible, reflection-free JSON serialization with compile-time type metadata.

## When to Use

- Preparing application for Native AOT compilation
- Eliminating reflection-based serialization overhead
- Improving startup performance by generating serialization code at compile time
- Ensuring JSON serialization errors surface at compile time

## Requirements

- .NET 8 or higher for full options support
- .NET 6+ for basic source generation

## Steps

1. **Invoke polymorphic skill first**:
   - Run `dotnet-json-polymorphic` skill to ensure polymorphic types are configured
   - This ensures `[JsonDerivedType]` attributes are in place before generating context

2. **Ask scope**:
   - Ask user: "Apply to entire solution or specific project?"
   - Filter to ASP.NET Core projects (those with web SDK or API endpoints)

3. **Scan for API endpoint types**:
   - Search for Minimal API patterns: `MapGet`, `MapPost`, `MapPut`, `MapDelete`, `MapPatch`
   - Extract request/response types from lambda parameters and return types

4. **Scan for controller types**:
   - Search for controller attributes: `[HttpGet]`, `[HttpPost]`, `[HttpPut]`, `[HttpDelete]`, `[HttpPatch]`
   - Extract parameter types and return types from action methods

5. **Find direct serialization calls**:
   - Search for `JsonSerializer.Serialize` and `JsonSerializer.Deserialize` calls
   - Extract type arguments from these calls

6. **Check for existing JsonSerializerContext**:
   - Search for classes inheriting from `JsonSerializerContext`
   - Note existing `[JsonSerializable]` types to avoid duplicates

7. **Ask about enum serialization**:
   - Ask user: "Enable enum-as-string converter? (Recommended: Yes)"

8. **Ask about property naming**:
   - Ask user: "Select property naming policy:"
     - CamelCase (Recommended)
     - SnakeCaseLower
     - SnakeCaseUpper
     - KebabCaseLower
     - KebabCaseUpper
     - None (preserve original casing)

9. **Ask about null value handling**:
   - Ask user: "Serialize null values? (Recommended: No)"
     - No - Omit null properties from output (smaller payloads)
     - Yes - Include null properties in output
   - If No: Add `DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull`

10. **Create JsonSerializerContext**:
    - File: `{ProjectName}JsonContext.cs` in project root (same level as Program.cs)
    - Class name: `{ProjectName}JsonContext`

11. **Add source generation options**:
    ```csharp
    [JsonSourceGenerationOptions(
        PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
    [JsonSerializable(typeof(WeatherForecast))]
    [JsonSerializable(typeof(List))]
    public partial class MyApiJsonContext : JsonSerializerContext
    {
    }
    ```

12. **Include collection types**:
    - For each type `T`, also add `[JsonSerializable(typeof(List))]`
    - Add `[JsonSerializable(typeof(T[]))]` if arrays are used

13. **Configure ASP.NET Core**:
    - Add to Program.cs:
    ```csharp
    builder.Services.ConfigureHttpJsonOptions(options =>
    {
        options.SerializerOptions.TypeInfoResolver = MyApiJsonContext.Default;
    });
    ```

14. **Verify with build**:
    ```bash
    dotnet build
    ```

15. **Report results**:
    - List the JsonSerializerContext file created
    - List all types added to [JsonSerializable]
    - Confirm ASP.NET Core integration added
    - Confirm build status

## Example Context

```csharp
using System.Text.Json;
using System.Text.Json.Serialization;

namespace MyApi;

[JsonSourceGenerationOptions(
    PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    Converters = [typeof(JsonStringEnumConverter)])]
[JsonSerializable(typeof(WeatherForecast))]
[JsonSerializable(typeof(List))]
[JsonSerializable(typeof(CreateOrderRequest))]
[JsonSerializable(typeof(OrderResponse))]
[JsonSerializable(typeof(List))]
[JsonSerializable(typeof(ErrorResponse))]
public partial class MyApiJsonContext : JsonSerializerContext
{
}
```

## ASP.NET Core Integration

**Program.cs:**
```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolver = MyApiJsonContext.Default;
});

var app = builder.Build();

app.MapGet("/weather", () => new WeatherForecast("Seattle", 72));
app.MapPost("/orders", (CreateOrderRequest request) => Results.Ok(new OrderResponse()));

app.Run();
```

## AOT Configuration

For full AOT compatibility, add to the `Directory.Build.props` file (preferred), or project file:

```xml

  false

```

This ensures compile-time errors if any type is missing from the context.

## Notes

- **Context naming**: Use `{ProjectName}JsonContext` for consistency
- **File location**: Place in project root alongside Program.cs
- **Collection types**: Always include `List` and array types if used in APIs
- **Polymorphic types**: Run `dotnet-json-polymorphic` first; polymorphic types use metadata-based generation only
- **Enum handling**: `JsonStringEnumConverter` requires .NET 8+ for AOT support
- **Multiple contexts**: Can have multiple contexts; use `JsonTypeInfoResolver.Combine()` to merge them

## Documentation

- [System.Text.Json Source Generation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation)

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Im5tu](https://github.com/Im5tu)
- **Source:** [Im5tu/claude](https://github.com/Im5tu/claude)
- **License:** MIT
- **Homepage:** https://codewithstu.tv

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-im5tu-claude-dotnet-source-gen-json
- Seller: https://agentstack.voostack.com/s/im5tu
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
