C#
JSON
deserialization
automatic properties
programming

C automatic property deserialization of JSON

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, JSON can be deserialized directly into classes that use automatic properties. This works well when the JSON shape matches the model and serializer settings are explicit. Most problems come from property-name mismatches, nullable values, or assuming deserialization also performs domain validation.

Automatic Properties Work Naturally with System.Text.Json

A plain DTO with get and set accessors is enough for most cases.

csharp
1using System;
2using System.Text.Json;
3
4public class UserDto
5{
6    public int Id { get; set; }
7    public string Name { get; set; } = string.Empty;
8    public bool Active { get; set; }
9}
10
11public class Program
12{
13    public static void Main()
14    {
15        string json = """
16        {
17          "id": 42,
18          "name": "Ada",
19          "active": true
20        }
21        """;
22
23        var options = new JsonSerializerOptions
24        {
25            PropertyNameCaseInsensitive = true
26        };
27
28        UserDto? user = JsonSerializer.Deserialize<UserDto>(json, options);
29        Console.WriteLine($"{user?.Id} {user?.Name} {user?.Active}");
30    }
31}

The serializer maps JSON fields to automatic properties as long as it can match names and convert types.

Map Different JSON Names with Attributes

If the JSON uses snake case or other naming that does not match your C# property names, use JsonPropertyName.

csharp
1using System.Text.Json.Serialization;
2
3public class ProductDto
4{
5    [JsonPropertyName("product_id")]
6    public int ProductId { get; set; }
7
8    [JsonPropertyName("display_name")]
9    public string DisplayName { get; set; } = string.Empty;
10}

This is usually clearer than relying on global naming assumptions for one-off fields.

Nested Objects and Lists Also Deserialize Automatically

Automatic properties work for child objects and collections too, as long as the model structure mirrors the JSON.

csharp
1using System.Collections.Generic;
2
3public class OrderDto
4{
5    public string OrderId { get; set; } = string.Empty;
6    public List<OrderItemDto> Items { get; set; } = new();
7}
8
9public class OrderItemDto
10{
11    public string Sku { get; set; } = string.Empty;
12    public int Qty { get; set; }
13}

That means manual JSON walking is usually unnecessary unless the shape is highly dynamic.

Deserialization Is Not Validation

A deserialized object is only parsed data. It may still be invalid for your business rules. A missing name, an empty identifier, or an unexpected enum value can all deserialize successfully but still be unusable.

csharp
1if (user is null || string.IsNullOrWhiteSpace(user.Name))
2{
3    throw new InvalidOperationException("Invalid payload");
4}

Treat deserialization and validation as separate steps. This is one of the most important habits in API code.

Common Serializer Options Matter

The defaults may not match your contract. Useful options include case-insensitive matching, enum handling, and ignoring unknown fields only when that is a deliberate compatibility choice.

Be explicit in shared code paths so a serializer upgrade or library switch does not change behavior silently.

Records and Init-Only Models

Modern C# projects sometimes use records or init-only properties for DTOs. Those can deserialize cleanly too, but only if the serializer can bind the incoming JSON shape to the available constructor or property set. When using stricter model styles, add a small contract test so you know deserialization still works after refactors.

Common Pitfalls

  • Assuming property names will match without attributes or serializer options.
  • Forgetting to initialize non-nullable reference properties sensibly.
  • Treating a successfully deserialized object as fully valid domain data.
  • Mixing System.Text.Json and Newtonsoft.Json behavior without checking differences.
  • Using dynamic parsing when a small DTO would be clearer and safer.

Summary

  • C# automatic properties deserialize cleanly from JSON when the model shape matches.
  • 'System.Text.Json works well for simple and nested DTOs.'
  • Use JsonPropertyName when JSON field names differ from C# property names.
  • Deserialization does not replace validation.
  • Explicit serializer configuration keeps JSON contracts easier to maintain.

Course illustration
Course illustration

All Rights Reserved.