Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool

C# and .NET JSON Formatter Implementation

JSON (JavaScript Object Notation) has become the de facto standard for data interchange in modern applications. Whether you're building web APIs, configuration systems, or data storage solutions, you'll inevitably work with JSON. While parsing and serializing JSON are common tasks, JSON formattingis equally important for both human readability and machine efficiency.

Formatting JSON typically involves controlling whitespace and indentation. The two primary styles are:

  • Pretty-Printing: Adding indentation and line breaks to make the JSON structure clear and easy for humans to read. Useful for debugging, configuration files, and documentation.
  • Compacting: Removing all unnecessary whitespace (spaces, tabs, newlines) to minimize the size of the JSON string. Useful for reducing bandwidth in network communication or saving storage space.

In this guide, we'll explore how to implement these formatting techniques in C# using the most common .NET libraries: the built-in `System.Text.Json` and the popular third-party `Newtonsoft.Json`.

Understanding .NET's JSON Libraries

Before diving into formatting, it's crucial to understand the two major players in the .NET JSON ecosystem:

  • System.Text.Json (STJ): Introduced in .NET Core 3.0 and the default in .NET 5+. It's designed for high performance, low memory allocation, and security. It's the recommended choice for new .NET applications.
  • Newtonsoft.Json (Json.NET): A long-standing and very popular third-party library. It's feature-rich, flexible, and has a wide range of configuration options and support for complex scenarios (like handling circular references, custom conversions, etc.). Many existing .NET projects use it.

Both libraries provide ways to serialize and deserialize JSON, and crucially, control its formatting.

Implementing Formatting with System.Text.Json (STJ)

System.Text.Json provides formatting options primarily through the JsonSerializerOptions class when serializing objects or Utf8JsonWriter when writing JSON manually. For formatting an existing JSON string, you'll typically parse it into a Document Object Model (DOM) representation using JsonDocument and then write it out with formatting.

Pretty-Printing JSON with STJ

To pretty-print an object or a JsonDocument, you use JsonSerializerOptions with the WriteIndented property set to true.

Example: Pretty-Printing using System.Text.Json

using System.Text.Json;

public static class StjJsonFormatter
{
    public static string PrettyPrint(string jsonString)
    {
        try
        {
            // Option 1: Parse then write (best for already existing JSON strings)
            using (JsonDocument doc = JsonDocument.Parse(jsonString))
            {
                var options = new JsonSerializerOptions
                {
                    WriteIndented = true // This is the key for pretty-printing
                };
                return JsonSerializer.Serialize(doc.RootElement, options);
            }

            /*
            // Option 2: Directly serialize an object with options
            // (If you have the object, not the string)
            // var myObject = new { Name = "Alice", Age = 30 };
            // var options = new JsonSerializerOptions { WriteIndented = true };
            // return JsonSerializer.Serialize(myObject, options);
            */
        }
        catch (JsonException ex)
        {
            // Handle invalid JSON input
            Console.WriteLine($"Error parsing JSON: {ex.Message}");
            return "Invalid JSON Input";
        }
    }
}

// Example Usage:
// string compactJson = "{\"name\":\"Bob\",\"isStudent\":true,\"courses\":[\"Physics\",\"Chemistry\"]}";
// string prettyJson = StjJsonFormatter.PrettyPrint(compactJson);
// Console.WriteLine(prettyJson);
/* Expected Output:
{
  "name": "Bob",
  "isStudent": true,
  "courses": [
    "Physics",
    "Chemistry"
  ]
}
*/

Compacting JSON with STJ

Compacting JSON with STJ is often simpler, as the default serialization behavior is to minimize whitespace.

Example: Compacting using System.Text.Json

using System.Text.Json;

public static class StjJsonFormatter
{
    public static string Compact(string jsonString)
    {
        try
        {
            // Option 1: Parse then write (best for already existing JSON strings)
            using (JsonDocument doc = JsonDocument.Parse(jsonString))
            {
                // Default options do not include indentation, resulting in compact output
                var options = new JsonSerializerOptions
                {
                    // WriteIndented = false is the default, no need to set explicitly
                };
                return JsonSerializer.Serialize(doc.RootElement, options);
            }

            /*
            // Option 2: Directly serialize an object with default options
            // var myObject = new { Name = "Alice", Age = 30 };
            // return JsonSerializer.Serialize(myObject); // Default is compact
            */
        }
        catch (JsonException ex)
        {
            // Handle invalid JSON input
            Console.WriteLine($"Error parsing JSON: {ex.Message}");
            return "Invalid JSON Input";
        }
    }
}

// Example Usage:
// string prettyJson = @"
// {
//   ""name"": ""Charlie"",
//   ""city"": ""London""
// }";
// string compactJson = StjJsonFormatter.Compact(prettyJson);
// Console.WriteLine(compactJson);
/* Expected Output:
{"name":"Charlie","city":"London"}
*/

Notice that for compacting, you often don't need special options; the default serialization behavior handles it.

Using JsonDocument for Flexibility

When formatting an arbitrary JSON string (not an object you've just created), parsing it into a JsonDocument first, as shown in the examples, is the standard approach.JsonDocument provides a read-only DOM that represents the JSON structure. You can then write this structure back out with different formatting options. This is efficient because it avoids full deserialization into C# objects if you only need to reformat.

Implementing Formatting with Newtonsoft.Json

Newtonsoft.Json uses JsonConvert.SerializeObject with the Formatting enumeration to control indentation. It also provides a powerful JObject/JArray (LINQ to JSON) API for working with JSON as a dynamic object model.

Pretty-Printing JSON with Newtonsoft.Json

Pretty-printing with Newtonsoft is done by setting the Formatting parameter of JsonConvert.SerializeObject to Formatting.Indented.

Example: Pretty-Printing using Newtonsoft.Json

using Newtonsoft.Json;
using Newtonsoft.Json.Linq; // Required for JObject/JArray parsing

public static class NewtonsoftJsonFormatter
{
    public static string PrettyPrint(string jsonString)
    {
        try
        {
            // Option 1: Parse then write (best for already existing JSON strings)
            // JToken is the base class for JObject, JArray, JValue etc.
            JToken parsedJson = JToken.Parse(jsonString);

            // Formatting.Indented applies indentation
            return parsedJson.ToString(Formatting.Indented);

            /*
            // Option 2: Directly serialize an object with formatting
            // (If you have the object, not the string)
            // var myObject = new { Product = "Book", Price = 19.95 };
            // return JsonConvert.SerializeObject(myObject, Formatting.Indented);
            */
        }
        catch (JsonReaderException ex)
        {
            // Handle invalid JSON input
            Console.WriteLine($"Error parsing JSON: {ex.Message}");
            return "Invalid JSON Input";
        }
    }
}

// Example Usage:
// string compactJson = "{\"id\":101,\"active\":false}";
// string prettyJson = NewtonsoftJsonFormatter.PrettyPrint(compactJson);
// Console.WriteLine(prettyJson);
/* Expected Output:
{
  "id": 101,
  "active": false
}
*/

Compacting JSON with Newtonsoft.Json

To compact JSON using Newtonsoft.Json, you can either omit the Formattingparameter or explicitly set it to Formatting.None.

Example: Compacting using Newtonsoft.Json

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public static class NewtonsoftJsonFormatter
{
    public static string Compact(string jsonString)
    {
        try
        {
            // Option 1: Parse then write (best for already existing JSON strings)
            JToken parsedJson = JToken.Parse(jsonString);

            // Formatting.None removes indentation (this is often the default)
            return parsedJson.ToString(Formatting.None);

            /*
            // Option 2: Directly serialize an object without formatting parameter
            // var myObject = new { Item = "Laptop", Qty = 1 };
            // return JsonConvert.SerializeObject(myObject); // Default is compact
            */
        }
        catch (JsonReaderException ex)
        {
            // Handle invalid JSON input
            Console.WriteLine($"Error parsing JSON: {ex.Message}");
            return "Invalid JSON Input";
        }
    }
}

// Example Usage:
// string prettyJson = @"
// {
//   ""status"": ""Ok"",
//   ""code"": 200
// }";
// string compactJson = NewtonsoftJsonFormatter.Compact(prettyJson);
// Console.WriteLine(compactJson);
/* Expected Output:
{"status":"Ok","code":200}
*/

Similar to STJ, the default behavior for JsonConvert.SerializeObjectwhen no Formatting option is specified is typically to produce compact JSON.

Using JObject/JArray for Manipulation

Newtonsoft's LINQ to JSON API (JObject, JArray, JValue, etc.) is very powerful for reading, modifying, and writing JSON structures dynamically without mapping to C# classes. When you use JToken.Parse or JObject.Parse/JArray.Parse, you get a mutable DOM that you can manipulate before writing it back out using ToString() with the desired Formatting. This is useful for more complex formatting tasks, like sorting object keys.

Performance Considerations

For typical use cases, both STJ and Newtonsoft are fast enough for formatting. However, when dealing with very large JSON strings or processing JSON in performance-critical loops, consider the following:

  • Parsing Cost: Converting a JSON string into a DOM (JsonDocument or JToken) requires reading and understanding the entire string. This parsing step is often the most expensive part.
  • STJ vs. Newtonsoft: Generally, System.Text.Json is designed to be faster and allocate less memory than Newtonsoft.Json for common scenarios, especially parsing and serialization. If performance is paramount and STJ meets your feature needs, it's the preferred choice.
  • Streaming: For extremely large JSON files that don't fit comfortably in memory, consider using streaming APIs (like Utf8JsonReader and Utf8JsonWriterin STJ, or JsonReader and JsonWriter in Newtonsoft). These allow you to process the JSON token by token without building a full in-memory DOM. Formatting directly via streaming writers gives you fine-grained control but is more complex than using the DOM approach.

For simple pretty-printing or compacting of strings that fit in memory, the parse-then-write approach with JsonDocument (STJ) or JToken (Newtonsoft) is idiomatic and readable.

Choosing the Right Tool

The choice between System.Text.Json and Newtonsoft.Json for JSON formatting depends on your project's context:

  • New Projects (.NET Core 3.0+ / .NET 5+): Start with System.Text.Json. It's built-in, high-performance, and sufficient for most formatting tasks (pretty/compact).
  • Existing Projects using Newtonsoft: Continue using Newtonsoft.Jsonfor consistency. It's well-maintained and provides powerful formatting options including its flexible LINQ to JSON API for more complex manipulations.

Conclusion

Implementing JSON formatting in C# is a straightforward task thanks to the capabilities of both System.Text.Json and Newtonsoft.Json. Whether you need to enhance readability through pretty-printing or optimize size by compacting, the core methods involve utilizing serialization options or writing from a parsed JSON structure with specific formatting flags. Understanding the strengths of each library allows you to pick the best approach for your specific formatting needs within the .NET ecosystem.

Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool