JSON to C#: generate classes for System.Text.Json
Deserializing JSON in .NET starts with classes that mirror the payload. This JSON to C# generator writes them for you from a sample: one partial class per object shape, auto-properties in PascalCase, and .NET types chosen from the values it sees. In full mode the output targets System.Text.Json, the serializer built into .NET, with attributes and converters ready to use.
Example
{
"id": 42,
"title": "Write docs",
"done": false,
"priority": 2.5,
"tags": ["docs"],
"owner": { "name": "Ada", "email": null },
"due": "2026-10-01T09:00:00Z",
"subtasks": [
{ "title": "Outline", "estimate": 2 },
{ "title": "Draft" }
]
}
With Types only checked:
namespace QuickType
{
public partial class Task
{
public long Id { get; set; }
public string Title { get; set; }
public bool Done { get; set; }
public double Priority { get; set; }
public string[] Tags { get; set; }
public Owner Owner { get; set; }
public DateTimeOffset Due { get; set; }
public Subtask[] Subtasks { get; set; }
}
public partial class Subtask
{
public string Title { get; set; }
public long? Estimate { get; set; }
}
}
Estimate is long? because one subtask lacks it. Whole numbers use long to avoid overflow surprises, decimals use double, arrays become C# arrays, and the ISO date string becomes DateTimeOffset, which keeps the time zone offset. The null-only email is typed as object.
Why the attributes matter
JSON keys are usually camelCase or snake_case, while C# properties are PascalCase. System.Text.Json matches property names case-sensitively by default, so Title will not pick up "title" unless you configure it. With Types only off, every property gets an attribute such as [JsonPropertyName("title")], so mapping works regardless of serializer options, even for keys like user_name or 2fa. The full output also includes:
Task.FromJson(string)and aToJson()extension method.- A
Converter.Settingsobject with converters for ISO dates, plusDateOnlyandTimeOnlysupport. - A
#nullable enablecontext and pragmas that silence nullable warnings in the generated file.
If you use bare classes instead, set PropertyNameCaseInsensitive = true or a JsonNamingPolicy in JsonSerializerOptions; ASP.NET Core's default options already use camelCase with case-insensitive matching.
Type mapping
| JSON | C# |
|---|---|
| integer | long (long? if optional) |
| decimal | double |
| ISO date-time | DateTimeOffset |
| array | T[] |
| object | partial class named after the key |
| null only / mixed | object |
For money, change double to decimal; binary floating point cannot represent values like 0.1 exactly. Change arrays to List<T> if you add items after deserializing.
Nullable reference types
The full output enables nullable reference types with #nullable enable. Properties that were always present in your sample are declared as non-nullable string, so the compiler assumes they are never null. If the real API can omit them, change them to string?; otherwise you may meet a NullReferenceException at runtime even though the compiler raised no warning.
Customizing the output
- Namespace: replace
QuickTypewith your project's namespace. - Records: for immutable DTOs, turn classes into
public record Subtask(string Title, long? Estimate);; System.Text.Json supports records. - Newtonsoft.Json: if your project uses it, swap
[JsonPropertyName]for[JsonProperty]. - Required members: on C# 11+, mark mandatory properties with
requiredto catch missing data at compile time when constructing objects.
Format the generated file with the C# Formatter. Working from XML? See XML to C#. To check your input, use the JSON Validator. All generation runs in your browser.