JSON to C#
Paste JSON, get C# classes or records with the right attributes, nullable annotations and List types.
Attributes that are actually needed
By default the generator only writes a name attribute when the C# property name differs from
the JSON key. That keeps the output readable — but it is worth knowing why the attribute
is required in those cases: System.Text.Json matches property names
case-sensitively unless you configure otherwise, so Id would silently come back
as 0 from a payload containing "id".
public class Root
{
[JsonPropertyName("id")]
public long Id { get; set; }
[JsonPropertyName("isActive")]
public bool IsActive { get; set; }
[JsonPropertyName("website")]
public string? Website { get; set; }
} Turn on Attribute every property if your team prefers explicit mapping on every member, or if you are serialising into a system where the casing rules are not under your control.
Class or record
Classes use mutable auto-properties, which is what most serialisers and ORMs expect. Records
are positional and immutable — shorter and better for value-like payloads, but the constructor
arguments must be matched by name, so the attribute becomes a property: target:
public record Root(
[property: JsonPropertyName("id")] long Id,
[property: JsonPropertyName("name")] string Name
); Type mapping
| JSON value | C# type | Nullable form |
|---|---|---|
| whole number | long | long? |
| decimal number | double | double? |
true / false | bool | bool? |
| string | string | string? |
| array | List<T> | List<T>? |
| object | its own class | — |
null | — | the ? form |
| mixed or unknown | object | object? |
The ? annotations need a nullable context
A question mark on a reference type is only meaningful when nullable reference types are
enabled. Add this to your .csproj, or the compiler will warn:
<PropertyGroup> <Nullable>enable</Nullable> <LangVersion>latest</LangVersion> </PropertyGroup>
Deserialising the payload
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var payload = JsonSerializer.Deserialize<Root>(body, options);
Console.WriteLine(payload?.Address?.City); Edge cases worth knowing
- Newtonsoft versus System.Text.Json. The only difference in the output is the
attribute name and namespace —
[JsonProperty]fromNewtonsoft.Jsonversus[JsonPropertyName]fromSystem.Text.Json.Serialization. - C# naming keeps
Id, notID. That matches the .NET framework design guidelines; the wire spelling is preserved by the attribute. - A key that starts with a digit is not a legal C# identifier, so it gains an
underscore (
_2fa) and the attribute carries the real key. - Mixed arrays become
List<object>; there is no common base type to describe[1, "two"]more precisely.
FAQ
Why does a nested object get its own top-level class?
C# allows many classes in one file and nested types are not required, so each object is emitted as a sibling class. That makes the types reusable and easy to move into their own files.
Should I use Newtonsoft or System.Text.Json?
System.Text.Json is the built-in choice for anything targeting .NET Core 3.0 or later and needs no package. Pick Newtonsoft when you are already using it, or need its more permissive converters and case-insensitive defaults.
Can I change the class names?
Yes — set Root name before copying. Nested class names come from the keys in your sample, so rename them in the JSON if you want different types.
Is my JSON uploaded?
No. Nothing leaves this browser tab.