Newtonsoft.Json Tutorial - Complete C# JSON Guide

Master JSON in C# with Newtonsoft.Json (Json.NET)

Published: January 2025 • 12 min read

Newtonsoft.Json (also known as Json.NET) is the most popular JSON framework for .NET. It's a powerful, flexible library that makes working with JSON in C# incredibly easy. Whether you're parsing API responses, working with configuration files, or building web services, Newtonsoft.Json is an essential tool.

This comprehensive guide covers everything from basic serialization to advanced features like custom converters and LINQ to JSON. You can also use our JSON to C# converter to generate C# classes from JSON data automatically.

Installation: Install via NuGet:Install-Package Newtonsoft.Json

Basic Serialization and Deserialization

The JsonConvert class provides simple methods for converting between C# objects and JSON strings. Read more in the official documentation.

Serialize Object to JSON

using Newtonsoft.Json;

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public bool IsActive { get; set; }
}

// Create object
var user = new User
{
    Id = 1,
    Name = "Alice Johnson",
    Email = "[email protected]",
    IsActive = true
};

// Serialize to JSON string
string json = JsonConvert.SerializeObject(user);
Console.WriteLine(json);

// Output: {"Id":1,"Name":"Alice Johnson","Email":"[email protected]","IsActive":true}

The object is converted to a compact JSON string.

Deserialize JSON to Object

using Newtonsoft.Json;

string json = @"{
    ""Id"": 1,
    ""Name"": ""Alice Johnson"",
    ""Email"": ""[email protected]"",
    ""IsActive"": true
}";

// Deserialize JSON string to object
User user = JsonConvert.DeserializeObject<User>(json);

Console.WriteLine($"ID: {user.Id}");
Console.WriteLine($"Name: {user.Name}");
Console.WriteLine($"Email: {user.Email}");

// Output:
// ID: 1
// Name: Alice Johnson
// Email: [email protected]

The JSON string is parsed into a strongly-typed C# object.

Pretty Printing JSON

Use Formatting.Indented to create human-readable JSON with proper indentation.

Formatted Output

using Newtonsoft.Json;

var user = new User
{
    Id = 1,
    Name = "Alice Johnson",
    Email = "[email protected]"
};

// Serialize with indentation
string json = JsonConvert.SerializeObject(user, Formatting.Indented);
Console.WriteLine(json);

// Output:
// {
//   "Id": 1,
//   "Name": "Alice Johnson",
//   "Email": "[email protected]"
// }

Perfect for debugging and logging. Learn more about formatting options.

Working with Collections

Newtonsoft.Json handles lists, arrays, and dictionaries seamlessly.

Serialize List to JSON Array

using Newtonsoft.Json;

var users = new List<User>
{
    new User { Id = 1, Name = "Alice", Email = "[email protected]" },
    new User { Id = 2, Name = "Bob", Email = "[email protected]" },
    new User { Id = 3, Name = "Charlie", Email = "[email protected]" }
};

string json = JsonConvert.SerializeObject(users, Formatting.Indented);
Console.WriteLine(json);

// Output:
// [
//   {
//     "Id": 1,
//     "Name": "Alice",
//     "Email": "[email protected]"
//   },
//   {
//     "Id": 2,
//     "Name": "Bob",
//     "Email": "[email protected]"
//   },
//   ...
// ]

Deserialize JSON Array to List

using Newtonsoft.Json;

string json = @"[
    {""Id"": 1, ""Name"": ""Alice"", ""Email"": ""[email protected]""},
    {""Id"": 2, ""Name"": ""Bob"", ""Email"": ""[email protected]""}
]";

List<User> users = JsonConvert.DeserializeObject<List<User>>(json);

foreach (var user in users)
{
    Console.WriteLine($"{user.Id}: {user.Name}");
}

// Output:
// 1: Alice
// 2: Bob

Dictionary Serialization

using Newtonsoft.Json;

var settings = new Dictionary<string, object>
{
    { "theme", "dark" },
    { "fontSize", 14 },
    { "notifications", true }
};

string json = JsonConvert.SerializeObject(settings, Formatting.Indented);
Console.WriteLine(json);

// Output:
// {
//   "theme": "dark",
//   "fontSize": 14,
//   "notifications": true
// }

JsonSerializerSettings - Advanced Configuration

Customize serialization behavior with JsonSerializerSettings. Learn more about all available settings.

Ignore Null Values

using Newtonsoft.Json;

var settings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
};

var user = new User
{
    Id = 1,
    Name = "Alice",
    Email = null  // This will be omitted
};

string json = JsonConvert.SerializeObject(user, Formatting.Indented, settings);
Console.WriteLine(json);

// Output:
// {
//   "Id": 1,
//   "Name": "Alice"
// }
// Note: Email is not included because it's null

Camel Case Property Names

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

var user = new User { Id = 1, Name = "Alice" };

string json = JsonConvert.SerializeObject(user, Formatting.Indented, settings);
Console.WriteLine(json);

// Output:
// {
//   "id": 1,
//   "name": "Alice"
// }
// Note: Properties are camelCase instead of PascalCase

Perfect for JavaScript APIs that expect camelCase. See naming strategies.

Date Format Handling

using Newtonsoft.Json;

public class Event
{
    public string Name { get; set; }
    public DateTime Timestamp { get; set; }
}

var settings = new JsonSerializerSettings
{
    DateFormatString = "yyyy-MM-dd HH:mm:ss"
};

var evt = new Event
{
    Name = "Meeting",
    Timestamp = DateTime.Now
};

string json = JsonConvert.SerializeObject(evt, Formatting.Indented, settings);
Console.WriteLine(json);

// Output:
// {
//   "Name": "Meeting",
//   "Timestamp": "2025-01-16 14:30:00"
// }

JSON Attributes for Fine Control

Use attributes to control how individual properties are serialized. Learn about all JSON attributes.

Common Attributes

using Newtonsoft.Json;

public class User
{
    [JsonProperty("user_id")]
    public int Id { get; set; }
    
    [JsonProperty("full_name")]
    public string Name { get; set; }
    
    [JsonIgnore]
    public string Password { get; set; }  // Never serialized
    
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public string Phone { get; set; }  // Ignored if default value
}

var user = new User
{
    Id = 1,
    Name = "Alice",
    Password = "secret123",  // Won't appear in JSON
    Phone = null
};

string json = JsonConvert.SerializeObject(user, Formatting.Indented);
Console.WriteLine(json);

// Output:
// {
//   "user_id": 1,
//   "full_name": "Alice"
// }
// Note: Password and Phone are not included

LINQ to JSON - Dynamic JSON

When you don't have a predefined class, use JObject and JArray for dynamic JSON manipulation. Read the LINQ to JSON guide.

Parse and Query with JObject

using Newtonsoft.Json.Linq;

string json = @"{
    ""user"": {
        ""id"": 1,
        ""name"": ""Alice"",
        ""settings"": {
            ""theme"": ""dark"",
            ""notifications"": true
        }
    }
}";

JObject obj = JObject.Parse(json);

// Access values
int userId = (int)obj["user"]["id"];
string name = (string)obj["user"]["name"];
string theme = (string)obj["user"]["settings"]["theme"];

Console.WriteLine($"User ID: {userId}");
Console.WriteLine($"Name: {name}");
Console.WriteLine($"Theme: {theme}");

// Output:
// User ID: 1
// Name: Alice
// Theme: dark

Create JSON Dynamically

using Newtonsoft.Json.Linq;

// Create JSON from scratch
JObject user = new JObject
{
    ["id"] = 1,
    ["name"] = "Alice",
    ["email"] = "[email protected]",
    ["roles"] = new JArray("admin", "user"),
    ["settings"] = new JObject
    {
        ["theme"] = "dark",
        ["notifications"] = true
    }
};

Console.WriteLine(user.ToString(Formatting.Indented));

// Output:
// {
//   "id": 1,
//   "name": "Alice",
//   "email": "[email protected]",
//   "roles": [
//     "admin",
//     "user"
//   ],
//   "settings": {
//     "theme": "dark",
//     "notifications": true
//   }
// }

Modify Existing JSON

using Newtonsoft.Json.Linq;

string json = @"{""name"": ""Alice"", ""age"": 30}";

JObject obj = JObject.Parse(json);

// Add new property
obj["email"] = "[email protected]";

// Modify existing property
obj["age"] = 31;

// Remove property
obj.Remove("age");

Console.WriteLine(obj.ToString());

// Output: {"name":"Alice","email":"[email protected]"}

Real-World Examples

Example 1: Reading API Response

using System.Net.Http;
using Newtonsoft.Json;

public class ApiResponse
{
    public bool Success { get; set; }
    public List<User> Data { get; set; }
}

// Fetch data from API
using (var client = new HttpClient())
{
    string json = await client.GetStringAsync("https://api.example.com/users");
    
    ApiResponse response = JsonConvert.DeserializeObject<ApiResponse>(json);
    
    if (response.Success)
    {
        foreach (var user in response.Data)
        {
            Console.WriteLine($"{user.Name} - {user.Email}");
        }
    }
}

Common pattern for consuming REST APIs.

Example 2: Configuration File

using Newtonsoft.Json;
using System.IO;

public class AppConfig
{
    public string ConnectionString { get; set; }
    public int Timeout { get; set; }
    public bool EnableLogging { get; set; }
}

// Read config from file
string json = File.ReadAllText("appsettings.json");
AppConfig config = JsonConvert.DeserializeObject<AppConfig>(json);

Console.WriteLine($"Connection: {config.ConnectionString}");
Console.WriteLine($"Timeout: {config.Timeout}s");

// Save config back to file
config.Timeout = 60;
string updatedJson = JsonConvert.SerializeObject(config, Formatting.Indented);
File.WriteAllText("appsettings.json", updatedJson);

Example 3: Error Handling

using Newtonsoft.Json;

string json = @"{""id"": 1, ""name"": ""Alice"", ""invalid"": }";  // Invalid JSON

try
{
    User user = JsonConvert.DeserializeObject<User>(json);
}
catch (JsonReaderException ex)
{
    Console.WriteLine($"Invalid JSON: {ex.Message}");
}
catch (JsonSerializationException ex)
{
    Console.WriteLine($"Serialization error: {ex.Message}");
}
catch (Exception ex)
{
    Console.WriteLine($"Unexpected error: {ex.Message}");
}

Always handle JsonReaderException and JsonSerializationException.

Best Practices

1.
Use strongly-typed classes: Define C# classes for known JSON structures instead of dynamic types
2.
Handle exceptions: Always wrap deserialization in try-catch blocks
3.
Use JsonSerializerSettings for consistency: Configure once and reuse across your application
4.
Consider System.Text.Json for new projects: Microsoft's built-in library is faster for simple scenarios
5.
Use [JsonIgnore] for sensitive data: Prevent passwords and secrets from being serialized
6.
Validate JSON with our tools: Use JSON Validator to check syntax before parsing

Newtonsoft.Json vs System.Text.Json

.NET Core 3.0+ includes System.Text.Json as a built-in alternative. Here's when to use each:

FeatureNewtonsoft.JsonSystem.Text.Json
PerformanceGoodFaster (optimized)
FeaturesVery richGrowing
LINQ to JSON✅ Yes (JObject)✅ Yes (JsonDocument)
Custom Converters✅ Extensive✅ Available
Circular References✅ Supported❌ Limited
InstallationNuGet packageBuilt-in (.NET Core 3.0+)

Recommendation:

  • Use Newtonsoft.Json if: You need advanced features, working with .NET Framework, or migrating existing code
  • Use System.Text.Json if: Starting a new .NET Core project and need maximum performance

External Resources

Summary

Newtonsoft.Json is a powerful, feature-rich library for working with JSON in C#. Key takeaways:

  • Use JsonConvert.SerializeObject() to convert objects to JSON
  • Use JsonConvert.DeserializeObject<T>() to parse JSON to objects
  • Customize behavior with JsonSerializerSettings and attributes
  • Use JObject and JArray for dynamic JSON
  • Always handle exceptions when parsing external JSON

Next Steps: Try our JSON to C# converter to automatically generate classes from JSON, or explore common issues on Stack Overflow.