JSON to C# classes
Paste a JSON response and the C# model for it appears as you type: plain classes, or POCOs, one per object shape, with each property mapped to its key. Nothing you paste leaves this tab.
How to use it#
- Paste a JSON sample into the box above, such as a response from the API you are calling.
- Name the root class, and choose classes or records.
- Pick the library that will read the JSON, so each property gets the right attribute.
- Copy the C# from beside the result, or download it as a .cs file.
How the C# types are chosen#
Text becomes string and true or false becomes bool. A number becomes int when every value seen in that place is a whole number that fits in 32 bits, long when one of them is larger, decimal when one is too big even for long, and double as soon as one has a fractional part. A price written as 12.0 counts as whole, since the zero is lost when the JSON is read, so include one real price such as 12.5 or change the type by hand. An object becomes a class of its own, named after the key it sits under, so a shipping_address key gives a ShippingAddress class, an array becomes a List of whatever it holds, and an object with no keys becomes Dictionary<string, object>.
Keys are turned into PascalCase property names, and every property keeps an attribute naming its JSON key exactly, so first_name maps to FirstName and still reads and writes as first_name. A key that would clash with its class name, or with another key once both are in PascalCase, is given a suffix rather than left to break the build.
A place that holds two different kinds of value, such as a number in one record and a string in another, or that the sample says nothing about, such as an empty array, becomes object. That compiles and deserializes, and it is the honest answer: the sample does not say which type it should be.
Nulls, missing keys, and nullable types#
A value that is null in the sample, or a key that some objects in an array leave out, gets a question mark: int? or string?. That is what lets the deserializer leave it empty rather than throw or silently store a zero. Keys present in every sample come out without one.
With nullable reference types switched on, the compiler warns about a string or List property that has no question mark and no value set in a constructor. Add the required modifier where the API always sends the field, or a default such as string.Empty, depending on how your project handles it. The sample alone cannot tell which fields the API promises.
Classes or records#
A class with get and set is the long-standing choice and works with every serializer and every version of .NET. A record with init accessors gives you value equality and properties that cannot be changed after the object is built, which suits a response you only read. System.Text.Json and Newtonsoft.Json both fill init properties, so pick whichever your codebase already uses.
When the JSON at the top level is an array or a single value rather than an object, C# has no way to name that type, so the output starts with a comment saying what to deserialize it as, such as List<RootItem>. Read the JSON into the model with JsonSerializer.Deserialize<Root>(json) in System.Text.Json, or JsonConvert.DeserializeObject<Root>(json) in Newtonsoft.Json. For the same model in TypeScript, use JSON to TypeScript, and for Go structs, JSON to Go.
Frequently asked questions#
Which serializer should I choose?
#
The one your project uses to read the JSON. System.Text.Json is built into .NET Core 3.0 and later and reads the JsonPropertyName attribute. Newtonsoft.Json, the Json.NET package, reads JsonProperty instead. Each ignores the other attribute, so choosing the wrong one leaves every renamed property empty after deserializing.
Why is a property typed as object?
#
Because the sample showed it holding more than one kind of value, only null, or nothing at all, as with an empty array. Replace object with the real type once you know it. Pasting several records where the field is filled in usually settles it.
How does it decide between int, long, and double?
#
From every number seen in that place. Whole numbers that fit in a 32 bit int give int, a larger one gives long, one past the range of long gives decimal, and any number with a fractional part gives double. An ID that is small in your sample but can grow past two billion should be changed to long by hand.
Should money be a double or a decimal?
#
A decimal. A number with a fractional part comes out as double, because that is the type that can hold any number in the JSON, but double cannot store most prices exactly, so 0.1 plus 0.2 is not 0.3. Change prices, totals, and rates to decimal by hand. System.Text.Json and Newtonsoft.Json both read a JSON number straight into a decimal.
Why is a date a string?
#
JSON has no date type, so a date in the sample is only text. If it is ISO 8601 text such as 2026-09-28T10:00:00Z, change the property to DateTime or DateTimeOffset, and both System.Text.Json and Newtonsoft.Json will read it.
Why do the properties have attributes when the names already match?
#
So the mapping does not depend on naming settings. By default System.Text.Json matches names exactly, and FirstName does not match first_name. With the attribute on every property, the class reads the same JSON whatever naming policy the project sets.
Is the JSON I paste sent anywhere?
#
No. It is parsed and converted in this browser tab as you type, so a response with real customer data in it stays on your machine.