This content originally appeared on DEV Community and was authored by mohamed Tayel
Records in C# provide a concise and immutable way to define data structures. Their built-in features make serialization and deserialization with System.Text.Json effortless. Whether you need a simple JSON representation or advanced customization, records offer great flexibility. This article dives into these features with multiple examples, covering common and advanced scenarios.
Serializing a Record to JSON
Serializing a record to JSON is straightforward. Let’s create a Student record and convert it into a JSON string:
using System.Text.Json;
public record Student(string Name, int Age);
class Program
{
static void Main()
{
var student = new Student("Alice", 21);
// Serialize the record to JSON
string json = JsonSerializer.Serialize(student);
Console.WriteLine(json);
}
}
Output:
{"Name":"Alice","Age":21}
Here, the JsonSerializer automatically maps the record properties to JSON key-value pairs.
Formatting JSON Output
To make the JSON output more readable, use the WriteIndented option:
var options = new JsonSerializerOptions { WriteIndented = true };
string indentedJson = JsonSerializer.Serialize(student, options);
Console.WriteLine(indentedJson);
Output:
{
"Name": "Alice",
"Age": 21
}
Deserializing JSON into a Record
The Deserialize method maps JSON back into a record instance. Let’s reverse the process:
string jsonInput = "{\"Name\":\"Alice\",\"Age\":21}";
// Deserialize JSON to a Student record
var deserializedStudent = JsonSerializer.Deserialize<Student>(jsonInput);
Console.WriteLine(deserializedStudent);
Output:
Student { Name = Alice, Age = 21 }
Customizing JSON Property Names
Sometimes, you need to rename JSON properties for external APIs or readability. Use [JsonPropertyName] to customize property names.
Example: Renaming Properties
using System.Text.Json.Serialization;
public record Product(
[property: JsonPropertyName("product_name")] string Name,
[property: JsonPropertyName("product_cost")] decimal Price
);
class Program
{
static void Main()
{
var product = new Product("Tablet", 600.00m);
// Serialize with custom JSON property names
string json = JsonSerializer.Serialize(product);
Console.WriteLine(json);
// Deserialize JSON back to Product
string jsonInput = "{\"product_name\":\"Tablet\",\"product_cost\":600.0}";
var deserializedProduct = JsonSerializer.Deserialize<Product>(jsonInput);
Console.WriteLine(deserializedProduct);
}
}
Output:
Serialized JSON:
{"product_name":"Tablet","product_cost":600.0}
Deserialized Record:
Product { Name = Tablet, Price = 600.0 }
Ignoring Properties During Serialization
You can exclude specific properties using the [JsonIgnore] attribute. Let’s extend the Product record with a field we want to ignore.
Example: Ignoring a Property
public record Product(
string Name,
decimal Price,
[property: JsonIgnore] string InternalCode
);
class Program
{
static void Main()
{
var product = new Product("Phone", 1200.00m, "SECRET123");
// Serialize to JSON
string json = JsonSerializer.Serialize(product);
Console.WriteLine(json);
// Deserialize JSON back to Product
string jsonInput = "{\"Name\":\"Phone\",\"Price\":1200.0}";
var deserializedProduct = JsonSerializer.Deserialize<Product>(jsonInput);
Console.WriteLine(deserializedProduct);
}
}
Output:
Serialized JSON:
{"Name":"Phone","Price":1200.0}
Deserialized Record:
Product { Name = Phone, Price = 1200.0, InternalCode = }
The InternalCode property is ignored during serialization but retains its default value when deserialized.
Advanced Scenarios
Ignoring Null Values
If you want to exclude null properties from JSON, use the DefaultIgnoreCondition option.
var options = new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
var product = new Product("Tablet", 500.00m, null);
string json = JsonSerializer.Serialize(product, options);
Console.WriteLine(json);
Output:
{"Name":"Tablet","Price":500.0}
Nested Records and Serialization
Records can be nested, and JSON serialization handles this seamlessly.
public record Address(string Street, string City);
public record Customer(string Name, Address Address);
class Program
{
static void Main()
{
var customer = new Customer("John", new Address("123 Main St", "Springfield"));
// Serialize to JSON
string json = JsonSerializer.Serialize(customer, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);
// Deserialize JSON back to Customer
string jsonInput = "{\"Name\":\"John\",\"Address\":{\"Street\":\"123 Main St\",\"City\":\"Springfield\"}}";
var deserializedCustomer = JsonSerializer.Deserialize<Customer>(jsonInput);
Console.WriteLine(deserializedCustomer);
}
}
Output:
Serialized JSON:
{
"Name": "John",
"Address": {
"Street": "123 Main St",
"City": "Springfield"
}
}
Deserialized Record:
Customer { Name = John, Address = Address { Street = 123 Main St, City = Springfield } }
Handling Arrays in Records
Records with array or collection properties are fully supported. Let’s serialize a record with a list of orders:
public record Order(int Id, string Product, int Quantity);
public record OrderBatch(string Customer, List<Order> Orders);
class Program
{
static void Main()
{
var batch = new OrderBatch(
"Alice",
new List<Order>
{
new Order(1, "Phone", 2),
new Order(2, "Tablet", 1)
}
);
// Serialize the order batch to JSON
string json = JsonSerializer.Serialize(batch, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);
// Deserialize JSON back to OrderBatch
string jsonInput = "{\"Customer\":\"Alice\",\"Orders\":[{\"Id\":1,\"Product\":\"Phone\",\"Quantity\":2},{\"Id\":2,\"Product\":\"Tablet\",\"Quantity\":1}]}";
var deserializedBatch = JsonSerializer.Deserialize<OrderBatch>(jsonInput);
Console.WriteLine(deserializedBatch);
}
}
Output:
Serialized JSON:
{
"Customer": "Alice",
"Orders": [
{
"Id": 1,
"Product": "Phone",
"Quantity": 2
},
{
"Id": 2,
"Product": "Tablet",
"Quantity": 1
}
]
}
Deserialized Record:
OrderBatch { Customer = Alice, Orders = [Order { Id = 1, Product = Phone, Quantity = 2 }, Order { Id = 2, Product = Tablet, Quantity = 1 }] }
Assignments
Easy Level
- Serialize a
Personrecord withNameandAgeinto JSON and print it. - Deserialize
{"Name":"Jane","Age":30}into aPersonrecord.
Medium Level
- Add a
[JsonPropertyName]attribute to thePersonrecord to renameNametofull_nameandAgetoperson_age. - Add a
PhoneNumberproperty toPersonand use[JsonIgnore]to exclude it from serialization.
Difficult Level
-
Create an
Invoicerecord with:-
InvoiceNumber(string),Amount(decimal), andDueDate(DateTime). - Use
[JsonPropertyName]to rename all properties for JSON output. - Exclude
DueDatefrom serialization using[JsonIgnore].
-
-
Create a
Companyrecord with:-
Name(string) andEmployees(List). - Serialize and deserialize the
Companyrecord with nestedPersonrecords.
-
Conclusion
Serializing and deserializing records in C# is straightforward, and with attributes like [JsonPropertyName] and [JsonIgnore], you can fine-tune how records interact with JSON. By mastering these features, you can create flexible, JSON-ready data models for real-world applications.
This content originally appeared on DEV Community and was authored by mohamed Tayel