JSON to C#
Generate C# types from a JSON sample. Properties are PascalCased with a [JsonPropertyName] attribute preserving the original key, and optional fields get nullable annotations so the compiler helps you handle missing data.
How to generate C# classes from JSON
- Paste a JSON sample — ideally an array of several records, so optional fields are detected.
- Set the Root type name. Nested objects are named after the key that holds them, singularised for arrays.
- Choose class for mutable models with
get; set;, or record for a concise immutable positional type. - Set a Namespace to get a file-scoped
namespace X;declaration. - Copy the code, or download it as a file.
Type mapping
- Integers →
long; fractional →double; booleans →bool; strings →string. - Arrays →
List<T>. Change toT[]orIReadOnlyList<T>to taste. - Objects → a named type.
- null / mixed →
object, or useJsonElementif you want to inspect it without a cast.
Getting good types out of a sample
Type inference from a sample is only as good as the sample. Three habits make the output far more useful:
- Paste an array, not one record. When you pass several records, a key missing from any of them is marked optional and a field that is sometimes a number and sometimes a float widens to a float. One record makes everything look required.
- Include the awkward cases. A record with a null, an empty array, and a missing optional key teaches the generator more than ten identical happy-path records.
- Check unions by hand. A field that holds different shapes in different records falls back to the language's "any" type. That is a signal your data has a variant the generator cannot express — model it explicitly.
Privacy
Nothing is uploaded. Inference and code generation run in this tab. No server sees the payload you paste — which matters, because real API responses tend to contain real user data.
FAQ
Does System.Text.Json need the attributes?
Only when names differ. Its default matching is case-insensitive for property names, so userName often binds to UserName without help — but user_name does not. Keeping the attributes makes the mapping explicit and survives a rename.
Can I use these with Newtonsoft.Json instead?
Yes, but swap [JsonPropertyName("x")] for [JsonProperty("x")] and the using directive for Newtonsoft.Json. The type shapes are identical.
Why long instead of int?
Because a sample cannot prove a value fits in 32 bits, and silently overflowing on a large ID is worse than an over-wide column. Narrow it once you know the range.