JSON (JavaScript Object Notation) has become the standard format for data exchange in modern applications. Whether you're building a web API, consuming a third-party service, or storing data in a NoSQL database, understanding JSON serialization in C# is essential. In this comprehensive guide, we'll explore everything you need to know about serializing and deserializing JSON in C# applications.
JSON serialization is the process of converting .NET objects into JSON format, while deserialization is the reverse process of converting JSON back into .NET objects. This conversion allows applications to exchange data in a language-agnostic format that's both human-readable and machine-parseable.
In C#, there are primarily two libraries for working with JSON:
Introduced in .NET Core 3.0, System.Text.Json is Microsoft's modern, high-performance JSON library. It's now the default JSON serializer in .NET 5 and later versions.
Originally created by James Newton-King, Newtonsoft.Json has been the de facto standard for JSON processing in .NET for many years. It offers extensive features and flexibility, making it popular in many existing projects.
Let's start with the modern approach using System.Text.Json. Here's a simple example of serializing an object to JSON:
using System.Text.Json;
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
var person = new Person { Id = 1, Name = "John Doe", Email = "john@example.com" };
string json = JsonSerializer.Serialize(person);
Console.WriteLine(json);
To deserialize JSON back to an object:
Person deserializedPerson = JsonSerializer.Deserialize<Person>(json);
Console.WriteLine(deserializedPerson.Name);
You can control how objects are serialized using attributes or options:
using System.Text.Json.Serialization;
public class Product
{
[JsonPropertyName("product_id")]
public int Id { get; set; }
[JsonIgnore]
public string InternalCode { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public Category Category { get; set; }
}
You can also configure serialization options globally:
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string json = JsonSerializer.Serialize(person, options);
If you're using Newtonsoft.Json, the syntax is slightly different but equally powerful:
using Newtonsoft.Json;
string json = JsonConvert.SerializeObject(person, Formatting.Indented);
Person deserializedPerson = JsonConvert.DeserializeObject<Person>(json);
Newtonsoft.Json offers more customization options through attributes like [JsonProperty], [JsonIgnore], etc.
Working with nested objects, collections, and complex data structures is straightforward:
public class Order
{
public int OrderId { get; set; }
public List<OrderItem> Items { get; set; }
public DateTime OrderDate { get; set; }
}
public class OrderItem
{
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
The serialization process automatically handles the nested structure, producing clean JSON output.
System.Text.Json was designed with performance in mind, offering better performance than Newtonsoft.Json in many scenarios. However, Newtonsoft.Json still has advantages in terms of flexibility and features.
For high-performance scenarios, consider using JsonSerializer.SerializeAsync and JsonSerializer.DeserializeAsync to avoid blocking I/O operations.
Q: How do I handle null values in JSON serialization?
A: By default, null values are included in the JSON output. You can exclude them by setting JsonSerializerOptions.DefaultIgnoreCondition to JsonIgnoreCondition.WhenWritingNull, which will prevent null properties from appearing in your JSON.
Q: Can I serialize private properties?
A: Yes, you can use JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.Never to include private properties. Alternatively, you can use reflection or attributes like [JsonIgnore] to control visibility.
Q: How do I handle date/time serialization?
A: By default, dates are serialized as ISO 8601 strings. You can customize this by adding converters to JsonSerializerOptions.Converters, which gives you full control over how dates are formatted.
Q: What's the difference between JsonSerializer and System.Text.Json?
A: JsonSerializer is the static class in System.Text.Json that provides the main serialization methods, while System.Text.Json is the entire namespace containing the library.
Q: How can I handle versioning in JSON APIs?
A: You can use attributes like [JsonProperty] with different names, implement custom converters, or use wrapper objects to handle different versions of your API contracts. This flexibility is particularly useful when maintaining backward compatibility.
C# offers powerful tools for JSON serialization through both System.Text.Json and Newtonsoft.json. While System.Text.Json is the modern, high-performance choice for new applications, Newtonsoft.json remains a solid option for projects requiring its extensive feature set.
Mastering JSON serialization is crucial for any C# developer working with modern applications. By understanding the concepts, best practices, and available options, you'll be able to implement robust data exchange mechanisms in your applications.
For more JSON-related tools and utilities, check out our JSON Pretty Print tool which helps you format and validate JSON strings instantly.