JSON to C#
Convert JSON to C# classes or C# 9+ records instantly. Supports System.Text.Json, Newtonsoft attributes, nullable reference types, and nested types.
Convert JSON to C# POCO classes or records instantly. All JSON keys are converted to PascalCase
properties, correct .NET types are inferred (int, double, bool, List<T>), and serialization attributes are added for seamless
System.Text.Json or Newtonsoft integration.
JSON to C# Type Mapping Reference
When converting untyped JSON data into strongly-typed C# data transfer objects (DTOs), the generator analyzes each JSON token to select the most idiomatic .NET type. The table below outlines how primitive values, complex structures, and collections are mapped.
| JSON Sample / Token | Generated C# Type | Nullable RTs Mode | Mapping Rule & Serialization Note |
|---|---|---|---|
| "username": "ada" | string | string? | Standard UTF-16 string mapping. With NRT enabled, marked nullable to prevent compiler warnings on omitted keys. |
| "age": 30 | int | int? | Inferred via Number.isInteger(). For IDs larger than 2,147,483,647, consider replacing with long. |
| "score": 98.6 | double | double? | Mapped to 64-bit IEEE double. For monetary or financial calculations, manually adjust to decimal in production. |
| "active": true | bool | bool? | Native boolean literal mapping. |
| "notes": null | object | object? | When a field has a null sample, the generator defaults to object as the fallback root type. |
| "tags": ["c#", "dotnet"] | List<string> | List<string>? | Uniform primitive array mapped to generic List<T> using System.Collections.Generic. |
| "items": [{"id": 1}] | List<Item> | List<Item>? | Object arrays trigger singularization of the key name (items → Item) and extract a separate class. |
| "created_at": "2026-08-15T..." | string | string? | ISO 8601 strings are output as raw string by default. Replace with DateTimeOffset for automatic time parsing. |
| "first-name": "Grace" | FirstName | FirstName? | Keys with hyphens, underscores, or camelCase are normalized to PascalCase with a matching attribute mapping. |
C# Classes vs. Positional Records for API Payloads
Modern .NET offers two primary paradigms for structuring DTOs: mutable class definitions with auto-properties, and immutable positional record declarations (available in C# 9+).
When to use Mutable Classes
- Legacy framework compatibility (.NET Framework 4.8 or older ASP.NET Web API).
- Bidirectional data-binding (WPF, Windows Forms, Blazor two-way bindings).
- Entity Framework Core tracking models requiring parameterless constructors and mutable setters.
- Complex inheritance hierarchies across multiple polymorphic data types.
When to use Positional Records
- High-performance API ingestion and microservices pipelines.
- Built-in structural value equality: two record instances with identical properties evaluate to
truein unit test assertions. - Non-destructive mutation using C#
with-expressions (var updated = item with { Price = 199.99 };). - Thread-safe data transfer across background worker services.
Below is a comparison of how the generator converts the same JSON payload into both forms:
using System.Text.Json.Serialization;
public class UserProfile
{
[JsonPropertyName("user_id")]
public int UserId { get; set; }
[JsonPropertyName("email")]
public string Email { get; set; }
} using System.Text.Json.Serialization;
public record UserProfile(
[property: JsonPropertyName("user_id")] int UserId,
[property: JsonPropertyName("email")] string Email
); Important note on record attributes: The generator prefixes record parameters with the [property: ...] target specifier. This ensures the compiler attaches the serialization attribute to the auto-generated property rather than only the constructor parameter.
System.Text.Json vs. Newtonsoft.Json (Json.NET)
Choosing the right attribute style depends on your project's target framework and serializer configuration. For an in-depth architectural breakdown and migration guide, read our dedicated article on System.Text.Json vs Newtonsoft.Json in modern .NET.
System.Text.Json (STJ)
Built directly into .NET Core 3.0+ and .NET 5+. Operates directly over UTF-8 byte spans without allocating intermediate strings, resulting in significantly lower memory allocation and higher throughput.
using System.Text.Json;
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
WriteIndented = true
};
// Deserialization
var model = JsonSerializer.Deserialize<Root>(jsonString, options); Newtonsoft.Json (Json.NET)
The historical standard in the .NET ecosystem. Features extensive flexibility, tolerant type coercion, support for legacy serialization callbacks, and JSONPath querying via JObject.SelectToken().
using Newtonsoft.Json;
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented
};
// Deserialization
var model = JsonConvert.DeserializeObject<Root>(jsonString, settings); Nullable Reference Types & The Sample Payload Trap
In C# 8 and later, projects with <Nullable>enable</Nullable> treat all reference types (string, arrays, class instances) as non-nullable by default. If a property is declared as public string Name { get; set; }, the C# compiler expects it to never be null.
null, or change shape during partial updates. If your generated C# model uses non-nullable types, deserializing a response where a key is missing will assign null to a non-nullable property, potentially causing unexpected NullReferenceException downstream.
Recommended practice: Enable the Nullable RTs toggle in the generator whenever working with external REST or GraphQL APIs. This appends ? to string and complex object types (string?, Category?), forcing calling code to handle possible null states safely.
Comparing jsonutils.app with Visual Studio & quicktype
Depending on your workflow, different JSON-to-C# conversion tools offer distinct trade-offs in speed, automation, and customization:
| Feature / Tool | jsonutils.app (This Tool) | Visual Studio (Paste JSON as Classes) | quicktype CLI / Web |
|---|---|---|---|
| Execution Context | 100% In-Browser (Client-side) | Integrated in Visual Studio IDE | CLI (Node.js) or Web service |
| C# 9+ Records Support | Yes (Positional syntax) | No (Classes only) | Yes (with CLI configuration) |
| Serializer Toggle | System.Text.Json / Newtonsoft / None | No attributes or legacy Newtonsoft | Newtonsoft / System.Text.Json |
| Nullable Reference Types | One-click toggle | No | Yes |
| Best Use Case | Instant generation, VS Code, Rider, Mac/Linux dev | Quick offline paste on Windows Visual Studio | Automated CI/CD build-time code generation |
If you work exclusively in Visual Studio on Windows, the built-in Edit > Paste Special > Paste JSON as Classes is very convenient for basic models. However, if you use JetBrains Rider, VS Code, Linux, or macOS, or if you need modern C# 9+ positional records with System.Text.Json attributes, jsonutils provides a faster and more customizable zero-install solution.
Related tools
Frequently asked questions
What is a C# POCO class?
POCO stands for Plain Old CLR Object — a simple C# class with no dependencies on
framework-specific base classes. POCOs are used to represent data structures (like API
response payloads) in a serializable, testable way. They typically contain auto-properties
({"{ get; set; }"}) and are decorated with JSON serialization attributes.
What is the difference between a C# class and a record?
Introduced in C# 9, records are reference types with value-based equality and built-in
immutability. Use a class when you need mutable data or inheritance.
Use a record
for immutable data transfer objects (DTOs) — the compiler generates
Equals,
ToString,
and with-expressions automatically.
When should I use [JsonPropertyName] vs [JsonProperty]?
Use [JsonPropertyName] from System.Text.Json.Serialization if you're on .NET 5+ (the built-in serializer). Use [JsonProperty] from Newtonsoft.Json if your project uses the Newtonsoft NuGet package — still common in .NET Framework and
older ASP.NET Core projects.
What are nullable reference types and when should I enable them?
Nullable reference types (NRTs, C# 8+) add compile-time null safety. With NRTs enabled,
string
cannot be null by default — you must explicitly use
string?
for nullable strings. Modern .NET projects enable NRTs by default in the
.csproj
file with {".
How are JSON arrays handled in C#?
JSON arrays become List<T> properties. If the array contains objects, a new class is generated for the item type
(named from the singular of the property key). Primitive arrays become
List<string>, List<int>, etc.
How do I deserialize JSON into these C# classes?
With System.Text.Json:
var obj = JsonSerializer.Deserialize<Root>(jsonString);. With Newtonsoft:
var obj = JsonConvert.DeserializeObject<Root>(jsonString);. Both will map JSON keys to the matching property using the attribute you've configured.
How do I resolve "JsonException: The JSON value could not be converted to System.Int32"?
This occurs in System.Text.Json when a JSON payload provides numbers formatted as quoted strings (e.g. "age": "25") or floating-point numbers where an integer was expected. Configure JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString or change the C# property type to double or long.
Why does JsonSerializer.Deserialize return null properties when JSON keys use camelCase?
System.Text.Json is strictly case-sensitive by default. If your C# class uses PascalCase properties (FirstName) without [JsonPropertyName("firstName")] attributes, deserialization fails to bind the values. To fix this globally, set PropertyNameCaseInsensitive = true in your JsonSerializerOptions.
How do I deserialize a JSON array at the root into a C# collection?
When an API response returns a top-level array [{...}, {...}] instead of a single object, deserialize directly into a generic collection type: var items = JsonSerializer.Deserialize<List<Item>>(jsonString);. You do not need a root wrapper class in this scenario.