Skip to content

Formatters & Code

JSON to C# Class

Generate POCO classes from a JSON sample.

Runs in your browser
JSON · source
lines: 17chars: 261size: 261 B
C# class · result
lines: 32chars: 902size: 902 B
live

Understanding JSON → C#

Two libraries, one mental model.

Why .NET has two JSON libraries, which one to pick now, and the attributes that map JSON keys to C# property names without surprises.

Newtonsoft vs System.Text.Json.

For almost two decades C# JSON meant Newtonsoft (Json.NET) — the de-facto library James Newton-King wrote in 2006 and Microsoft later licensed to a foundation. System.Text.Json shipped with .NET Core 3.0 in 2019 as the new default: faster, allocation-friendlier, but with a smaller surface. Modern projects should target System.Text.Json; legacy code can keep Newtonsoft. Codegen tools emit the attribute flavour for whichever library you pick.

The JsonPropertyName attribute.

C# convention is PascalCase property names; JSON keys are typically snake_case or camelCase. The bridge is [JsonPropertyName("user_id")] on a property named UserId — tells System.Text.Json what to call the field in JSON. For Newtonsoft the same attribute is [JsonProperty("user_id")]; otherwise functionally equivalent. A project-level naming policy (JsonNamingPolicy.SnakeCaseLower in .NET 8+) can avoid per-property attributes when the whole API uses one convention.

Nullable reference types.

C# 8 added nullable annotations (string? vs string) that flow through the type system. For JSON DTOs, mark every field that can be null or missing as nullable; the rest are required. Combined with required modifier (C# 11+), you get a compile-time guarantee that the field exists. The codegen tool's job is to emit nullables correctly based on the source schema — null values in samples become string?, never-null become string.

A worked example.

From { "user_id": 7, "name": "Q", "avatar": null }: public class User { [JsonPropertyName("user_id")] public int UserId { get; set; } public required string Name { get; set; } public string? Avatar { get; set; } } The avatar nullable; the name required; the user_id needs an attribute because the property name doesn't match. Sealed shape, idiomatic .NET.

Classic class

get;set; properties + System.Text.Json

Mutable; ergonomic for ORMs and forms.

public class User { ... required Name ... }

= Standard DTO shape

JsonStringEnumConverter.

Enums round-trip as integers by default, which is rarely what you want — the JSON "status": "Active" deserializes correctly into an enum only if you register JsonStringEnumConverter or annotate the type with [JsonConverter(typeof(JsonStringEnumConverter))]. The codegen output for a string-valued enum field always needs that converter to round-trip cleanly. Forgetting this turns "Active" into a deserialization error.

Init-only setters and records.

C# 9 added init-only setters: public string Name { get; init; } means the property can be set during object construction and never again. Combined with C# records (next chapter), this gives you immutable-by-default DTOs without giving up the deserializer's ability to set properties. The recommended modern shape: properties with init setters on a regular class, or a record (more on which is right when).

Source generators for high performance.

.NET 6 introduced JSON source generators — compile-time generated serializers that beat the reflection-based defaults by 2-5×. Annotate a partial context class with [JsonSerializable(typeof(User))], and the compiler emits zero-reflection deserialization code. For a hot path (request handling in a high-throughput service), source generators are free performance. For most application code, the default reflection-based path is fine.

Frequently asked questions

Quick answers.

How does the tool handle nested objects?

The generator recursively scans your JSON structure to create separate, linked classes for each nested object level. It ensures that complex hierarchies are mapped to a structured class model.

What attributes are added to the classes?

The tool can include `[JsonPropertyName]` or `[JsonProperty]` attributes to ensure proper deserialization when JSON keys use different naming conventions than C# properties. This supports both System.Text.Json and Newtonsoft.Json libraries.

How are data types determined?

It infers types based on the JSON values: integers become `int` or `long`, decimals become `double` or `decimal`, and ISO dates are mapped to `DateTime`. If a value is null, the tool defaults to `object` or a nullable type.

Is my data sent to any external server?

No. The conversion logic is executed entirely within your web browser. Neither your JSON structure nor the resulting C# code is transmitted or stored on any server.

People also search for

Related tools

More in this room.

See all in Formatters & Code