How to use the JSON to C#
- Paste a sample JSON document.
- Name the root class and pick the property naming (keep keys, camelCase or PascalCase).
- Review the types: whole numbers become long, decimals double, values that are null become nullable (object? when only null was seen).
- Copy the classes into your project and call JsonSerializer.Deserialize<Root>(json).
Worked example
An order with line items and a null shipping date
Input
{"orderId":"A-17","total":12.5,"items":[{"sku":"X1","qty":3}],"shippedAt":null}C#
using System.Collections.Generic;
public class Root
{
public string orderId { get; set; }
public double total { get; set; }
public List<Item> items { get; set; }
public object? shippedAt { get; set; }
}
public class Item
{
public string sku { get; set; }
public long qty { get; set; }
}Default naming keeps the JSON keys, so no attributes are needed. With PascalCase naming, orderId becomes OrderId plus [JsonPropertyName("orderId")]. shippedAt is only null in the sample, so its type is unknown (object?); if it is a timestamp, change it to DateTimeOffset?.
System.Text.Json vs. Newtonsoft.Json
| Task | System.Text.Json | Newtonsoft.Json |
|---|---|---|
| Rename a property | [JsonPropertyName("x")] | [JsonProperty("x")] |
| Case-insensitive matching | Off by default; on with JsonSerializerDefaults.Web | On by default |
| Deserialize | JsonSerializer.Deserialize<T>(json) | JsonConvert.DeserializeObject<T>(json) |
| Ships with .NET | Yes (.NET Core 3.0+) | NuGet package |
| Comments and trailing commas | Opt-in via JsonSerializerOptions | Tolerated |
double, decimal and big IDs
Decimals in the sample become double. The generator never emits decimal, so for prices and other money values change the type to decimal yourself; System.Text.Json reads it without binary rounding. Whole numbers always become long, which avoids int overflow on IDs; integers beyond long's range become BigInteger.
Nullable reference types
The generator adds ? only where the sample showed null or a missing key; there is no separate nullable-reference-types switch. With <Nullable>enable</Nullable>, string means "never null" to the compiler, yet JSON can omit the key. Mark fields that may be missing as string?, or add the required modifier (C# 11+) for keys that must always be present – System.Text.Json enforces required members since .NET 7.
JSON to C# FAQ
How do I deserialize JSON to a C# object?
With System.Text.Json: var root = JsonSerializer.Deserialize<Root>(json); with Newtonsoft.Json: JsonConvert.DeserializeObject<Root>(json). Generate the Root class here first.
Why are all my properties null after deserializing?
Usually a casing mismatch: System.Text.Json is case-sensitive by default, so "orderId" does not fill OrderId. Keep the default naming (properties match the keys), keep the JsonPropertyName attributes added with PascalCase naming, or pass new JsonSerializerOptions(JsonSerializerDefaults.Web).
Can Visual Studio generate classes from JSON?
Yes, Edit > Paste Special > Paste JSON As Classes does a similar job inside the IDE. This page is useful when you are not in Visual Studio or want attributes added.
Should I use records for JSON models in C#?
Records (C# 9+) work well for immutable DTOs and System.Text.Json can deserialize them through their constructor. Classes with setters remain the most compatible choice.
How do I map a JSON array at the root?
Deserialize into a list: JsonSerializer.Deserialize<List<Item>>(json). No wrapper class is needed.

