Browser processing Input is processed on your device. Privacy & storage

JSON to C#

Paste JSON, get C# classes or records with the right attributes, nullable annotations and List types.

JSON input
C# output

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 valueC# typeNullable form
whole numberlonglong?
decimal numberdoubledouble?
true / falseboolbool?
stringstringstring?
arrayList<T>List<T>?
objectits own class—
null—the ? form
mixed or unknownobjectobject?

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] from Newtonsoft.Json versus [JsonPropertyName] from System.Text.Json.Serialization.
  • C# naming keeps Id, not ID. 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.