Skip to content
ZeroServer.tools

JSON to C# Class Converter

Generate C# classes for System.Text.Json or Newtonsoft.Json from a JSON sample, with each key in an attribute. Every value is typed, and a key that some objects lack or hold as null is nullable.

JSON library
C# version
Nullable properties
or drop a file here
  • Order.Coupon, which some objects lack, is written back as null for them. NullValueHandling = NullValueHandling.Ignore leaves out a property that is null, and so leaves out a null the JSON has too.

About JSON to C#

The objects in the JSON become C# classes that System.Text.Json or Newtonsoft.Json reads the JSON into and writes back. With either library, every property has its key in an attribute, [JsonPropertyName] or [JsonProperty], so created_at is read into CreatedAt. Even a property named as its key has one, since System.Text.Json's naming policy, such as the camelCase one ASP.NET Core sets, renames only the properties without one.

Every value at a place counts, not just the first. A number is an int, a long once one is beyond 32 bits, and a double when one is written with a fraction or an exponent, as 10.0 and 1e3 are, since both libraries refuse those for an int. Integers beyond 64 bits are a ulong or a decimal when one reads them all, and a double otherwise.

The objects at one place, such as the items of a list, make one class, with the keys in the order first seen. A key that is null in some objects, or that some objects lack, is nullable: int?, and for C# 11 and later string? too. A note names each key that some objects lack, since both libraries write it back as null for them.

For C# 11 and later, the code starts with #nullable enable, and every property that is not nullable is required: System.Text.Json then throws on an object that lacks its key, where it would otherwise read 0 or null. Newtonsoft.Json does not check required. For .NET 6 and earlier, .NET Framework or Unity, choose C# 7.3 to 10: the code then has neither, since C# 7.3 has no #nullable and required came with C# 11.

A key that holds two kinds of value, such as a string and a number, or only null, is a JsonElement for System.Text.Json and a JToken for Newtonsoft.Json, each of which holds any JSON, and objects that are always empty are a JsonObject or a JObject. A note says why, as one does for each number a double rounds or cannot hold, each string Newtonsoft.Json takes for a date and writes back in its own format, and a JSON deeper than a library reads by default.

Properties and classes are PascalCase, so user_id, userID and USER_ID all give UserId, and a name already taken gets a number, as in UserId2. The class of a list's items is singular, as Order is for orders. A property named as its class, or as a method every object has, such as ToString, has Value added, and a class named as a type the SDK's implicit usings bring in, such as File or Task, has Model added.

When the JSON is an array of objects, the root class describes them, and a note gives the type that reads the whole array. Choose Every property to make every property nullable, for an API that can leave any key out. With No attributes, a property reads only the key its name gives, and a note names each key that differs from its property's name. Everything runs in your browser.

For Kotlin, see JSON to Kotlin Data Class. For Java, try JSON to Java Class, and for TypeScript, JSON to TypeScript.

Built and maintained by Meet Shah · Last updated

What this tool is used for

  • Generating System.Text.Json or Newtonsoft.Json models from an API response for an ASP.NET Core, Blazor or Unity app.
  • Getting the [JsonPropertyName] or [JsonProperty] right for keys in snake_case, or with characters a C# name cannot hold.
  • Starting a model for an endpoint that has no OpenAPI schema, from a response copied out of the browser or a log.
  • Checking where System.Text.Json and Newtonsoft.Json read the same JSON differently, from the notes, before moving a project between them.
  • Seeing how a payload's nesting maps onto nested C# classes, and which keys only some of its objects carry.

Frequently Asked Questions

How do JSON types map to C#?
Strings are string, booleans bool, objects a class and arrays a List<T>. A number is an int, a long beyond 32 bits, a ulong or decimal beyond 64, and a double when a sample has a fraction or an exponent, as 10.0 and 1e3 do. A key null in some samples is nullable, as in int?.
Why does every property have an attribute?
A property reads only the key its name gives, so created_at is read into CreatedAt through a [JsonPropertyName] or [JsonProperty] that holds the key. A property named as its key gets one too, since System.Text.Json's naming policy, such as ASP.NET Core's camelCase, renames only the properties without one.
Does System.Text.Json ignore case in property names?
Not by default: it reads a key only into the property of exactly its name, so name is not read into Name. With PropertyNameCaseInsensitive, as ASP.NET Core sets it, a class with keys that differ only by case throws an InvalidOperationException. Newtonsoft.Json tries the exact name, then ignores case.
Why are the properties required?
For C# 11 and later, every property that is not nullable is required, so the compiler gives no warning CS8618, and System.Text.Json throws a JsonException on an object that lacks its key, where it would otherwise read 0 or null. Newtonsoft.Json does not check required, and C# 7.3 to 10 has none.
Why is a property a JsonElement or a JToken?
A key with two kinds of value, such as a string and a number, or only null, fits no one C# type, so it is a JsonElement for System.Text.Json or a JToken for Newtonsoft.Json, which hold any JSON, with a note. Without attributes it is an object. Objects that are always empty are a JsonObject or a JObject.
Should every property be nullable?
A sample shows only some of the keys an API can send as null or leave out: here a key that is null is nullable, and so is one that some objects lack. The API contract says which others are. Every property makes them all nullable, and none required, so a response can leave any key out.

Common errors and gotchas

  • Generating from a sample where a decimal field happens to hold a whole number, such as a price of 12: the property is an int, and both libraries then refuse 12.5. Use a sample with a fraction, or write 12.0, which gives a double.
  • Trusting the nullability one sample shows: a key present in every object of the sample can still be left out of a real response, and System.Text.Json then throws for its required property. Choose Every property when the API contract does not say.
  • Leaving out the attributes and counting on System.Text.Json to ignore case: by default it reads name into no property called Name, and neither library reads user_name into UserName without an attribute or a policy such as JsonNamingPolicy.SnakeCaseLower.
  • Naming a class after a type .NET already has, such as File or Task: the class hides that type throughout its namespace, which is why a key named file gives a class FileModel here.
  • Letting Newtonsoft.Json read a date string into a JToken or object: it parses the date and writes it back in its own format, so .1230+05:30 comes back as .123+05:30. Set DateParseHandling = DateParseHandling.None to keep such strings as they are.
  • Posting deeply nested JSON to an ASP.NET Core MVC controller: its JsonOptions set MaxDepth = 32, so it throws on a JSON 33 levels deep that the defaults read. A note says so for a JSON that deep.

Related Developer Utilities tools

Private & free — this tool runs entirely in your browser.

IndieKit — Ship your Next.js startup in days.affiliate