Generate C# classes from JSON
Convert JSON into C# classes with System.Text.Json attributes, PascalCase properties, nullable reference types and List<T> collections.
- Runs in your browser
- Files are never uploaded
- Free, no account
The name given to the outermost type.
Your JSON never leaves this tab — check it yourself—
Starting the network probe…
The counter above wraps fetch, XMLHttpRequest and navigator.sendBeacon in this tab and counts every call. It does not block anything — it just reports.
Two ways to verify independently
- Turn off Wi-Fi or enable airplane mode, then use the tool. It keeps working, because the page is already fully loaded.
- Open your browser devtools, switch to the Network tab, clear it, and run the tool. No new row appears.
Why this matters
In 2025 researchers found that popular online formatters had retained tens of thousands of user-submitted snippets — JSONFormatter.org and CodeBeautify together exposed roughly 80,000 saved documents, many containing live cloud credentials, private keys and internal database connection strings, because “format this” quietly meant “upload this”. A separate incident exposed roughly 3.5 million user PDFs on a document-conversion service. The only structural fix is not sending the data in the first place: this site is served under a Content-Security-Policy whose connect-src contains no third-party origin, so a request off this device cannot be made even by accident.
What the generator produces
One public class per distinct nested object, with PascalCase auto-properties, and a
[JsonPropertyName("…")] attribute preserving the original JSON key. Collections
become List<T>. The two required using directives are included so the file
compiles as soon as you drop it into a project.
System.Text.Json or Newtonsoft?
The attributes target System.Text.Json, which is the in-box serialiser from .NET Core 3.0 onward
and the default in ASP.NET Core. If your project uses Newtonsoft.Json, the conversion is two
find-and-replaces: [JsonPropertyName("x")] becomes [JsonProperty("x")],
and the using directive becomes Newtonsoft.Json.
Worth knowing either way: System.Text.Json is case-insensitive only if you ask
(PropertyNameCaseInsensitive = true), whereas Newtonsoft is by default. The explicit
attributes make the difference irrelevant, which is why they are always emitted.
Numeric type choices
Whole numbers become long and fractional numbers become double. Both are
deliberate defaults rather than the obvious ones:
longbecause JSON integers regularly exceed 32 bits — Unix milliseconds already do, and so does any Snowflake-style ID.doublebecause that is precisely what a JSON number is under the specification’s interoperability guidance.
For money, change the property to decimal — and make sure the API sends the value as
a string, because a monetary amount that has already been through a double on the server has
already lost precision, and no client-side type can recover it.
Nullable reference types
Values that were null in your sample, and keys missing from some records, get ?.
Reference-type properties that were always present are emitted without it, which under
<Nullable>enable</Nullable> produces CS8618 — “non-nullable property
must contain a non-null value when exiting constructor”. Three ways to resolve it:
- Add
requiredto the property (C# 11 and later) — the clearest signal. - Initialise with
= string.Empty;or= new();where a sensible empty value exists. - Declare a constructor that takes the required values.
Do not reach for = null!; as a habit — it silences the compiler and keeps the bug.
Converting to records
If you want immutability, the change is mechanical. Either turn each set into
init, which keeps the class shape and the attributes, or rewrite as a positional
record:
public record Customer(
[property: JsonPropertyName("id")] long Id,
[property: JsonPropertyName("full_name")] string FullName);
Note the property: target — without it the attribute lands on the constructor
parameter and the serialiser ignores it.
Deserialising safely
Two options worth setting on JsonSerializerOptions: UnmappedMemberHandling.Disallow
(.NET 8+) turns an unexpected key into an exception rather than a silent drop, which is how you
learn the API changed; and NumberHandling = JsonNumberHandling.AllowReadingFromString
saves you when a provider sends numbers as strings inconsistently.
Questions
Which serialiser do the attributes target?
System.Text.Json — `[JsonPropertyName("…")]` from `System.Text.Json.Serialization`. If your project uses Newtonsoft.Json, replace the attribute with `[JsonProperty("…")]` and the using directive with `Newtonsoft.Json`; nothing else changes.
Why long and double instead of int and decimal?
long because JSON integers regularly exceed 32 bits, and double because that is what a JSON number is — an IEEE-754 double. For money, change the field to decimal by hand and make sure the API sends it as a string, or you will inherit the float rounding you were trying to avoid.
Do the properties handle nullable reference types?
Values that were null in the sample, and keys that were missing from some records, get `?`. Reference-type properties that were always present are emitted without it, which will warn under `<Nullable>enable</Nullable>` until you add a constructor or `required`.
Can I get records instead of classes?
Not automatically. Converting is mechanical though: change `class X { … }` to `record X(…)` with the properties as positional parameters, or add `init` accessors in place of `set` for an immutable class.