Skip to main content

C# JSON Handling

JSON (JavaScript Object Notation) has become the standard format for data exchange in modern applications. In this guide, we'll explore how to effectively work with JSON data in C# applications, from basic parsing to more complex operations.

Introduction to JSON in C#

JSON is a lightweight data interchange format that's easy for humans to read and write and easy for machines to parse and generate. It consists of key-value pairs and is commonly used for configuration files, API responses, and data storage.

C# provides multiple ways to work with JSON:

  1. System.Text.Json - The built-in JSON library introduced in .NET Core 3.0
  2. Newtonsoft.Json (Json.NET) - The most popular third-party library

In this tutorial, we'll cover both approaches so you can choose what works best for your projects.

Setting Up Your Environment

Using System.Text.Json

This library is built into .NET Core 3.0+ and .NET 5+, so no additional installation is needed.

Using Newtonsoft.Json

For Newtonsoft.Json, install the package:

bash
dotnet add package Newtonsoft.Json

Parsing JSON Data

Deserializing JSON to Objects

Let's start by converting JSON data into C# objects.

First, let's define a simple class:

csharp
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}

Using System.Text.Json

csharp
using System;
using System.Text.Json;

// JSON string
string jsonString = @"{
""Name"": ""John Smith"",
""Age"": 30,
""Email"": ""[email protected]""
}";

// Deserialize to object
Person person = JsonSerializer.Deserialize<Person>(jsonString);

// Access the data
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, Email: {person.Email}");

Output:

Name: John Smith, Age: 30, Email: [email protected]

Using Newtonsoft.Json

csharp
using Newtonsoft.Json;

// JSON string
string jsonString = @"{
""Name"": ""John Smith"",
""Age"": 30,
""Email"": ""[email protected]""
}";

// Deserialize to object
Person person = JsonConvert.DeserializeObject<Person>(jsonString);

// Access the data
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, Email: {person.Email}");

Reading JSON from a File

It's common to store JSON data in files. Here's how to read and parse JSON from a file:

csharp
using System.IO;
using System.Text.Json;
// or using Newtonsoft.Json;

// Read JSON file
string jsonFromFile = File.ReadAllText("person.json");

// Deserialize to object (System.Text.Json)
Person person = JsonSerializer.Deserialize<Person>(jsonFromFile);
// OR (Newtonsoft.Json)
// Person person = JsonConvert.DeserializeObject<Person>(jsonFromFile);

Console.WriteLine($"Loaded from file - Name: {person.Name}, Age: {person.Age}");

Creating and Modifying JSON

Serializing Objects to JSON

Now let's create JSON data from C# objects:

Using System.Text.Json

csharp
using System;
using System.Text.Json;

// Create an object
Person person = new Person
{
Name = "Sarah Johnson",
Age = 28,
Email = "[email protected]"
};

// Serialize to JSON string
string jsonString = JsonSerializer.Serialize(person);

// Print the JSON
Console.WriteLine(jsonString);

// For pretty printing (formatted JSON)
string prettyJson = JsonSerializer.Serialize(person, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine(prettyJson);

Output:

{"Name":"Sarah Johnson","Age":28,"Email":"[email protected]"}

{
"Name": "Sarah Johnson",
"Age": 28,
"Email": "[email protected]"
}

Using Newtonsoft.Json

csharp
using Newtonsoft.Json;

// Create an object
Person person = new Person
{
Name = "Sarah Johnson",
Age = 28,
Email = "[email protected]"
};

// Serialize to JSON string
string jsonString = JsonConvert.SerializeObject(person);

// Print the JSON
Console.WriteLine(jsonString);

// For pretty printing (formatted JSON)
string prettyJson = JsonConvert.SerializeObject(person, Formatting.Indented);
Console.WriteLine(prettyJson);

Writing JSON to a File

Saving JSON data to a file is straightforward:

csharp
// Create an object
Person person = new Person
{
Name = "Alex Wilson",
Age = 25,
Email = "[email protected]"
};

// System.Text.Json
string jsonString = JsonSerializer.Serialize(person, new JsonSerializerOptions
{
WriteIndented = true
});

// Newtonsoft.Json
// string jsonString = JsonConvert.SerializeObject(person, Formatting.Indented);

// Write JSON to file
File.WriteAllText("person_data.json", jsonString);
Console.WriteLine("JSON data saved to file successfully.");

Working with Complex JSON Structures

Arrays and Lists in JSON

JSON often contains arrays. Let's see how to work with them:

csharp
using System;
using System.Collections.Generic;
using System.Text.Json;

// Define a class with a list
public class Team
{
public string TeamName { get; set; }
public List<Person> Members { get; set; }
}

// Create sample data
Team team = new Team
{
TeamName = "Development",
Members = new List<Person>
{
new Person { Name = "Alice", Age = 32, Email = "[email protected]" },
new Person { Name = "Bob", Age = 28, Email = "[email protected]" },
new Person { Name = "Charlie", Age = 35, Email = "[email protected]" }
}
};

// Serialize to JSON
string jsonTeam = JsonSerializer.Serialize(team, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine(jsonTeam);

// Deserialize back
string jsonData = jsonTeam;
Team loadedTeam = JsonSerializer.Deserialize<Team>(jsonData);

// Access the data
Console.WriteLine($"Team: {loadedTeam.TeamName}");
foreach (var member in loadedTeam.Members)
{
Console.WriteLine($" - {member.Name}, {member.Age}");
}

Output:

json
{
"TeamName": "Development",
"Members": [
{
"Name": "Alice",
"Age": 32,
"Email": "[email protected]"
},
{
"Name": "Bob",
"Age": 28,
"Email": "[email protected]"
},
{
"Name": "Charlie",
"Age": 35,
"Email": "[email protected]"
}
]
}

Team: Development
- Alice, 32
- Bob, 28
- Charlie, 35

Nested Objects

JSON structures often contain nested objects:

csharp
using System.Text.Json;

public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}

public class Employee
{
public string Name { get; set; }
public int EmployeeId { get; set; }
public Address WorkAddress { get; set; }
public Address HomeAddress { get; set; }
}

// Create a nested object
Employee employee = new Employee
{
Name = "David Miller",
EmployeeId = 12345,
WorkAddress = new Address
{
Street = "123 Business Ave",
City = "Corporate City",
ZipCode = "10001",
Country = "USA"
},
HomeAddress = new Address
{
Street = "456 Home Street",
City = "Hometown",
ZipCode = "20002",
Country = "USA"
}
};

// Serialize to JSON
string jsonEmployee = JsonSerializer.Serialize(employee, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine(jsonEmployee);

// Deserialize back
Employee loadedEmployee = JsonSerializer.Deserialize<Employee>(jsonEmployee);
Console.WriteLine($"{loadedEmployee.Name} lives in {loadedEmployee.HomeAddress.City} " +
$"and works in {loadedEmployee.WorkAddress.City}");

Dynamic JSON Handling

Sometimes you don't know the JSON structure in advance or don't want to create classes for it. Here's how to work with dynamic JSON data:

Using System.Text.Json

csharp
using System;
using System.Text.Json;

string jsonString = @"{
""Name"": ""John Smith"",
""Details"": {
""Age"": 30,
""IsActive"": true
},
""Skills"": [""C#"", ""JSON"", "".NET""]
}";

using JsonDocument doc = JsonDocument.Parse(jsonString);
JsonElement root = doc.RootElement;

// Access properties
string name = root.GetProperty("Name").GetString();
int age = root.GetProperty("Details").GetProperty("Age").GetInt32();
bool isActive = root.GetProperty("Details").GetProperty("IsActive").GetBoolean();

Console.WriteLine($"Name: {name}, Age: {age}, Active: {isActive}");

// Access array
Console.WriteLine("Skills:");
JsonElement skills = root.GetProperty("Skills");
foreach (JsonElement skill in skills.EnumerateArray())
{
Console.WriteLine($" - {skill.GetString()}");
}

Using Newtonsoft.Json

csharp
using Newtonsoft.Json.Linq;

string jsonString = @"{
""Name"": ""John Smith"",
""Details"": {
""Age"": 30,
""IsActive"": true
},
""Skills"": [""C#"", ""JSON"", "".NET""]
}";

// Parse JSON
JObject jObject = JObject.Parse(jsonString);

// Access properties
string name = (string)jObject["Name"];
int age = (int)jObject["Details"]["Age"];
bool isActive = (bool)jObject["Details"]["IsActive"];

Console.WriteLine($"Name: {name}, Age: {age}, Active: {isActive}");

// Access array
Console.WriteLine("Skills:");
JArray skills = (JArray)jObject["Skills"];
foreach (var skill in skills)
{
Console.WriteLine($" - {skill}");
}

Handling JSON Customization

Custom Property Names

Often JSON property names don't match your C# property names. Here's how to handle that:

Using System.Text.Json

csharp
using System.Text.Json.Serialization;

public class Product
{
[JsonPropertyName("product_id")]
public int Id { get; set; }

[JsonPropertyName("product_name")]
public string Name { get; set; }

[JsonPropertyName("unit_price")]
public decimal Price { get; set; }
}

// Example usage
string jsonProduct = @"{
""product_id"": 101,
""product_name"": ""Laptop"",
""unit_price"": 999.99
}";

Product product = JsonSerializer.Deserialize<Product>(jsonProduct);
Console.WriteLine($"Product: {product.Name}, Price: ${product.Price}");

Using Newtonsoft.Json

csharp
using Newtonsoft.Json;

public class Product
{
[JsonProperty("product_id")]
public int Id { get; set; }

[JsonProperty("product_name")]
public string Name { get; set; }

[JsonProperty("unit_price")]
public decimal Price { get; set; }
}

Real-World Application: Configuration Files

JSON is commonly used for application configuration. Let's create a simple example:

csharp
using System;
using System.IO;
using System.Text.Json;

public class AppConfig
{
public string ApplicationName { get; set; }
public string Version { get; set; }
public DatabaseConfig Database { get; set; }
public LoggingConfig Logging { get; set; }

public class DatabaseConfig
{
public string ConnectionString { get; set; }
public int TimeoutSeconds { get; set; }
public bool UseSSL { get; set; }
}

public class LoggingConfig
{
public string LogLevel { get; set; }
public string LogPath { get; set; }
public bool ConsoleOutput { get; set; }
}
}

// Application startup code
class ConfigExample
{
static void Main()
{
// Check if config exists, if not create default
if (!File.Exists("appconfig.json"))
{
CreateDefaultConfig();
}

// Load configuration
AppConfig config = LoadConfiguration();

// Use the configuration
Console.WriteLine($"Starting {config.ApplicationName} v{config.Version}");
Console.WriteLine($"Database connection: {config.Database.ConnectionString}");
Console.WriteLine($"Log level: {config.Logging.LogLevel}, Path: {config.Logging.LogPath}");
}

static void CreateDefaultConfig()
{
AppConfig defaultConfig = new AppConfig
{
ApplicationName = "My Awesome App",
Version = "1.0.0",
Database = new AppConfig.DatabaseConfig
{
ConnectionString = "Server=localhost;Database=myapp;User Id=sa;Password=P@ssw0rd;",
TimeoutSeconds = 30,
UseSSL = true
},
Logging = new AppConfig.LoggingConfig
{
LogLevel = "Info",
LogPath = "logs/app.log",
ConsoleOutput = true
}
};

string jsonConfig = JsonSerializer.Serialize(defaultConfig, new JsonSerializerOptions
{
WriteIndented = true
});

File.WriteAllText("appconfig.json", jsonConfig);
Console.WriteLine("Created default configuration file.");
}

static AppConfig LoadConfiguration()
{
string jsonConfig = File.ReadAllText("appconfig.json");
return JsonSerializer.Deserialize<AppConfig>(jsonConfig);
}
}

Real-World Application: Working with REST APIs

When working with REST APIs, handling JSON is essential. Here's a simple example of making an API call and processing JSON response:

csharp
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

public class ApiClient
{
private HttpClient client = new HttpClient();

public async Task<User> GetUserAsync(int userId)
{
// Make HTTP request
HttpResponseMessage response = await client.GetAsync($"https://jsonplaceholder.typicode.com/users/{userId}");

// Ensure success
response.EnsureSuccessStatusCode();

// Read content as string
string jsonResponse = await response.Content.ReadAsStringAsync();

// Deserialize JSON to object
User user = JsonSerializer.Deserialize<User>(jsonResponse,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

return user;
}

public async Task DisplayUserInfoAsync(int userId)
{
try
{
User user = await GetUserAsync(userId);
Console.WriteLine($"User: {user.Name}");
Console.WriteLine($"Email: {user.Email}");
Console.WriteLine($"Company: {user.Company.Name}");
Console.WriteLine($"Address: {user.Address.Street}, {user.Address.City}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}

public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public Address Address { get; set; }
public string Phone { get; set; }
public string Website { get; set; }
public Company Company { get; set; }
}

public class Address
{
public string Street { get; set; }
public string Suite { get; set; }
public string City { get; set; }
public string Zipcode { get; set; }
public Geo Geo { get; set; }
}

public class Geo
{
public string Lat { get; set; }
public string Lng { get; set; }
}

public class Company
{
public string Name { get; set; }
public string CatchPhrase { get; set; }
public string Bs { get; set; }
}

// Usage example
static async Task Main()
{
ApiClient client = new ApiClient();
await client.DisplayUserInfoAsync(1);
}

Summary

In this tutorial, we've covered:

  1. The basics of JSON handling in C# using both System.Text.Json and Newtonsoft.Json
  2. Deserializing JSON to C# objects
  3. Serializing C# objects to JSON
  4. Reading and writing JSON from/to files
  5. Handling complex JSON structures with arrays and nested objects
  6. Working with dynamic JSON data
  7. Customizing JSON serialization
  8. Real-world applications: Configuration files and REST API integration

JSON is a fundamental skill for modern C# development, especially when working with web applications, APIs, and configuration systems. With the techniques you've learned in this tutorial, you'll be well-equipped to handle JSON data effectively in your C# applications.

Additional Resources and Exercises

Further Learning Resources

  1. Official Microsoft Documentation on System.Text.Json
  2. Newtonsoft.Json Documentation
  3. JSON Schema - For validating JSON data structures

Exercises

  1. Todo List App: Create a simple console app that manages a to-do list using JSON for storage
  2. JSON Config Editor: Build a small utility that can read, modify, and save JSON configuration files
  3. API Explorer: Create a tool that lets you fetch data from a public API, display it, and possibly save it to a file
  4. JSON Converter: Write a program that can convert between JSON and CSV formats
  5. Weather Dashboard: Build a console app that fetches weather data from a public API and displays formatted information

By completing these exercises, you'll gain practical experience working with JSON in C# applications and reinforce what you've learned in this tutorial.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)