csharp-scripts
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file…
Imperative guidance for the System.Text.Json APIs added in .NET 11: the built-in `JsonNamingPolicy.PascalCase` naming policy, and the strongly-typed `JsonSerializerOptions.GetTypeInfo<T>()` and `JsonSerializerOptions.TryGetTypeInfo<T>(out JsonTypeInfo<T>? info)` metadata
$ npx -y skills add dotnet/skills --skill system-text-json-net11 --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/system-text-json-net11Context preview
The summary Claude sees to decide when to auto-load this skill.
Imperative guidance for the System.Text.Json APIs added in .NET 11: the built-in `JsonNamingPolicy.PascalCase` naming policy, and the strongly-typed `JsonSerializerOptions.GetTypeInfo<T>()` and `JsonSerializerOptions.TryGetTypeInfo<T>(out JsonTypeInfo<T>? info)` metadata
name: system-text-json-net11 description: > Imperative guidance for the System.Text.Json APIs added in .NET 11: the built-in `JsonNamingPolicy.PascalCase` naming policy, and the strongly-typed `JsonSerializerOptions.GetTypeInfo<T>()` and `JsonSerializerOptions.TryGetTypeInfo<T>(out JsonTypeInfo<T>? info)` metadata accessors. USE ONLY when the user is targeting net11.0 or later and needs PascalCase JSON property or dictionary-key names without writing a custom naming policy, a strongly-typed `JsonTypeInfo<T>` instead of the non-generic `JsonTypeInfo`, or a no-throw way to probe whether a type's serialization metadata is resolved. DO NOT USE when the target is earlier than net11.0, the requested behavior uses an established pre-net11 naming policy, or the user explicitly selected another JSON library. license: MIT
Three APIs were added to `System.Text.Json` in .NET 11. This skill tells you exactly when to reach for each one, what to write, what **not** to write, and how to prove the result runs. Do not describe these APIs to the user — apply them, then run the code and show the output.
| API | Replaces the pre-.NET-11 workaround of... | | --- | --- | | `JsonNamingPolicy.PascalCase` (static property) | writing a custom `JsonNamingPolicy` subclass or hand-annotating every member with `[JsonPropertyName]` | | `JsonSerializerOptions.GetTypeInfo<T>()` | calling non-generic `GetTypeInfo(typeof(T))` and casting to `JsonTypeInfo<T>` | | `JsonSerializerOptions.TryGetTypeInfo<T>(out JsonTypeInfo<T>? info)` | wrapping `GetTypeInfo` in `try`/`catch` to probe availability |
These APIs only exist in the .NET 11 base class library. Before writing code:
1. Run `dotnet --list-sdks` and confirm an SDK that can target `net11.0` is present — an `11.x` SDK, or a later SDK with the `net11.0` targeting pack. 2. If the user explicitly asks you to run the sample and no suitable SDK is installed, use the official `dotnet-install` script to install the current .NET 11 SDK into a temporary or project-local directory. Prefer the GA channel build. Use a preview only when GA is not yet available or the user explicitly requested a preview. Do not require administrator access, change the machine-wide `PATH`, or replace an installed SDK. 3. Run the sample with that local `dotnet` executable. If download or execution is blocked, still provide the complete `net11.0` program and report that it was **not run**. Never substitute `net10.0`, a custom naming policy, or a different API and present that as validation of the .NET 11 feature.
Use the channel, not a guessed version. Try the GA channel first:
$installScript = Join-Path $env:TEMP "dotnet-install-$([guid]::NewGuid()).ps1"
try {
Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -OutFile $installScript
& $installScript -Channel 11.0 -InstallDir .\.dotnet
& .\.dotnet\dotnet.exe run --project <PATH_TO_NET11_PROJECT>
}
finally {
Remove-Item -LiteralPath $installScript -Force -ErrorAction SilentlyContinue
}install_script="$(mktemp "${TMPDIR:-/tmp}/dotnet-install.XXXXXX")"
trap 'rm -f "$install_script"' EXIT
curl -fsSL https://dot.net/v1/dotnet-install.sh -o "$install_script"
bash "$install_script" --channel 11.0 --install-dir ./.dotnet
./.dotnet/dotnet run --project <PATH_TO_NET11_PROJECT>Before .NET 11 GA, retry the install with `-Quality preview` (PowerShell) or `--quality preview` (shell).
Match the user's request to a row, apply the **Do this** cell verbatim, and confirm the **Verify** column before you are done.
| User asks for… | Do this (on `net11.0`) | Never do this | Verify | | --- | --- | --- | --- | | PascalCase JSON property names | `options.PropertyNamingPolicy = JsonNamingPolicy.PascalCase;` | define `class …: JsonNamingPolicy`; add per-member `[JsonPropertyName]`; string-case the names yourself | output JSON keys are PascalCase — e.g. `"Name"`, `"Age"` | | PascalCase dictionary keys | `options.DictionaryKeyPolicy = JsonNamingPolicy.PascalCase;` | set only `PropertyNamingPolicy`; pre-transform the dictionary; define a custom policy | dictionary keys such as `pendingOrders` become `"PendingOrders"` | | Strongly-typed metadata `JsonTypeInfo<T>` | set `TypeInfoResolver = new DefaultJsonTypeInfoResolver()`, then `JsonTypeInfo<T> ti = options.GetTypeInfo<T>();` | `(JsonTypeInfo<T>)options.GetTypeInfo(typeof(T))` | variable is typed `JsonTypeInfo<T>`, no cast | | Probe whether metadata is resolved | `if (options.TryGetTypeInfo<T>(out var ti)) { … } else { … }` | `try { options.GetTypeInfo<T>(); } catch (…) { … }` | no `try`/`catch`; both branches handled |
**When** the user wants JSON output whose property names are PascalCase (`Name`, `Age`) and asks for the built-in / framework-provided way:
1. Create or reuse a `JsonSerializerOptions` and set `PropertyNamingPolicy = JsonNamingPolicy.PascalCase`. 2. Serialize with those options.
Do **not** write a `JsonNamingPolicy` subclass, do **not** add `[JsonPropertyName("…")]` attributes to force casing, and do **not** upper-case the first letter of each name by hand. `JsonNamingPolicy.PascalCase` is the single correct answer on .NET 11.
// Console project (reflection enabled by default). To run this as a file-based app
// (dotnet run app.cs), also set TypeInfoResolver = new DefaultJsonTypeInfoResolver()
// — see "Producing runnable output" below.
using System.Text.Json;
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.PascalCase
};
string json = JsonSerializer.Serialize(new { name = "Jane", age = 30 }, options);
Console.WriteLine(json);
// {"Name":"Jane","Age":30}`PropertyNamingPolicy` does not transform `Dictionary<str
This repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.
Repo: dotnet/skills
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file…
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string marshalling, memory lifetime,…
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR: trusted publishing, NuGet…
Design, implement, optimize, and review SIMD code in .NET. USE FOR: vectorizing scalar loops with TensorPrimitives, Vector64/128/256/512, or platform hardware…
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET, Microsoft.Extensions.AI (MEAI), Microsoft Agent…
Configure OpenTelemetry distributed tracing, metrics, and logging in ASP.NET Core using the .NET OpenTelemetry SDK. Use when adding observability, setting up…