json csharp dotnet poco

JSON to C# Class Generator: From API Response to POCO in Seconds

How to use a JSON-to-C# converter to scaffold model classes from real API responses, database records, and config objects — and what to watch out for afterward.

· ByteKiln

You’ve just consumed a new API. The documentation is thin, but you have a sample response. Before you can write a single line of real code, you need a model class — and writing it by hand from a large JSON blob is tedious, error-prone, and the kind of work that should be automated.

That’s what the JSON to C# converter is for.


The Core Use Case

Paste a JSON response in; get idiomatic C# classes out.

Input:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "username": "alice_dev",
  "email": "alice@example.com",
  "registeredAt": "2025-03-12T14:30:00Z",
  "profile": {
    "bio": "Backend engineer",
    "avatarUrl": "https://example.com/avatars/alice.png",
    "followersCount": 1243
  },
  "roles": ["admin", "editor"],
  "settings": {
    "theme": "dark",
    "notifications": true
  }
}

Output:

public class Root
{
    public Guid Id { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    public DateTime RegisteredAt { get; set; }
    public Profile Profile { get; set; }
    public List<string> Roles { get; set; }
    public Settings Settings { get; set; }
}

public class Profile
{
    public string Bio { get; set; }
    public string AvatarUrl { get; set; }
    public int FollowersCount { get; set; }
}

public class Settings
{
    public string Theme { get; set; }
    public bool Notifications { get; set; }
}

Three classes, correct property types, PascalCase naming — generated in one step.


Type Inference: What Gets Detected

The converter analyzes JSON values and infers the most specific C# type that fits:

JSON valueInferred C# type
"hello"string
"2026-01-15T09:00:00Z"DateTime
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"Guid
42int
3.14double
true / falsebool
nullstring? (nullable)
{ }Nested class
[ ]List<T>
[ 1, 2, 3 ]List<int>
[ {...}, {...} ]List<ClassName>

The DateTime and Guid detection is particularly useful — without it, you’d get string for everything and have to manually identify and change those properties.


The Root Class Name Field

By default, the top-level object becomes a class named Root. If you know the semantic name of the type you’re modeling, enter it before generating:

  • Enter UserProfile → root class is public class UserProfile
  • Nested objects still get names derived from their JSON key

This saves you the rename step in your IDE afterward.


Handling Null Values

JSON APIs often return null for optional fields. The converter treats a null value as string? by default — a nullable string. In practice, you’ll want to review nullable properties and assign the correct type.

Example:

{
  "id": 1,
  "middleName": null,
  "deletedAt": null
}

Generated output:

public class Root
{
    public int Id { get; set; }
    public string? MiddleName { get; set; }
    public string? DeletedAt { get; set; }
}

DeletedAt is probably a DateTime?, not a string?. This is the kind of manual correction you’ll make after generation — but having string? is still better than string, and the property is at least correctly identified as nullable.


Arrays of Mixed Types

The JSON spec allows arrays to contain values of different types ([1, "two", true]), but C# generics don’t. The converter picks the best common type for an array. For truly heterogeneous arrays, it falls back to List<object>. In practice, well-designed APIs don’t use mixed-type arrays, so this edge case rarely comes up.


Using the Output in Real Code

The generated classes are a starting point. Before you use them in production:

1. Add the correct namespace

namespace MyApp.Models;

2. Add serialization attributes if needed

If you’re using System.Text.Json and the API uses camelCase keys:

using System.Text.Json.Serialization;

public class UserProfile
{
    [JsonPropertyName("username")]
    public string Username { get; set; }
}

Or configure the serializer globally:

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

3. Review nullable reference types

Check which properties can genuinely be null and add appropriate ? annotations. The generated code is a conservative starting point, not a production-ready model.

4. Add validation attributes if using ASP.NET

[Required]
[EmailAddress]
public string Email { get; set; }

5. Consider using records for immutable models

public record UserProfile(
    Guid Id,
    string Username,
    string Email,
    DateTime RegisteredAt
);

Practical Scenarios

Integrating a third-party REST API

You get sample responses from a vendor’s documentation or Postman collection. Generate the C# models, add a namespace, and you have a typed client model in minutes. Start calling JsonSerializer.Deserialize<VendorResponse>(json) immediately.

Building models from a database query result

If you’re using Dapper and you have a sample result set as JSON (from a monitoring tool or a test query), you can generate the class that matches the result shape. For the inverse — scaffolding the database table from the same C# model — the C# to SQL guide handles that translation. If you’re starting from JSON and need the schema too, the JSON to SQL guide generates CREATE TABLE statements directly from the sample response.

Prototyping fast

When building a proof of concept, you want to move quickly. Generate models from mock data, wire up your controller, and get the prototype running. Refine the models in a second pass.

Teaching yourself a new API

Paste a response you don’t understand. Read the generated class. The property names, types, and nesting make the API’s data model clear in C# terms — which is often more intuitive for a .NET developer than reading raw JSON.


What the Tool Doesn’t Do

  • No inheritance — all generated classes are standalone; it doesn’t detect is-a relationships between types.
  • No interfaces — it generates concrete classes, not interfaces like IUser.
  • No EF Core annotations[Key], [ForeignKey], [Column] are not added. The output is plain POCO, not EF model.
  • No JsonIgnore or converter attributes — those require domain knowledge the tool doesn’t have.

These are intentional — the tool generates a starting scaffold, not complete production models. The 80% that is mechanical is done for you; the remaining 20% that requires judgment is left for you.


Tips

Paste real API responses, not hand-written JSON. Real responses show you the actual nullability and type patterns you’ll encounter in production.

Use a single representative sample. If you have 100 records and you want to generate from a list, paste one item from the array to get the item model, not the full array.

Combine with the JSON Formatter first. If the response is minified, run it through the JSON Formatter to verify it’s valid and see its structure clearly before generating classes.


The JSON to C# converter removes the most tedious part of integrating an API or building a new service: the initial model scaffolding. Get the classes generated, add your namespace, adjust the nullability, and start writing the code that actually matters.