How do I get formatted JSON in .NET using C#?
Asked Answered
B

21

370

I am using .NET JSON parser and would like to serialize my config file so it is readable. So instead of:

{"blah":"v", "blah2":"v2"}

I would like something nicer like:

{
    "blah":"v", 
    "blah2":"v2"
}

My code is something like this:

using System.Web.Script.Serialization; 

var ser = new JavaScriptSerializer();
configSz = ser.Serialize(config);
using (var f = (TextWriter)File.CreateText(configFn))
{
    f.WriteLine(configSz);
    f.Close();
}
Biologist answered 18/4, 2010 at 3:54 Comment(2)
Just for reference: you're not really using "the" .NET JSON parser but rather an old parser created in the old ASP.NET days. Today there's also the new System.Text.Json parser that's way faster and is more considered the out-of-the-box parser to use now with .NET going forward. JSON.NET is also another very popular JSON library for .NET.Stipel
dvdmn's answer #2661563 doesn't require to have declared typesSukkoth
R
330

You are going to have a hard time accomplishing this with JavaScriptSerializer.

Try JSON.Net.

With minor modifications from JSON.Net example

using System;
using Newtonsoft.Json;

namespace JsonPrettyPrint
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Product product = new Product
                {
                    Name = "Apple",
                    Expiry = new DateTime(2008, 12, 28),
                    Price = 3.99M,
                    Sizes = new[] { "Small", "Medium", "Large" }
                };

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

            Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
        }
    }

    internal class Product
    {
        public String[] Sizes { get; set; }
        public decimal Price { get; set; }
        public DateTime Expiry { get; set; }
        public string Name { get; set; }
    }
}

Results

{
  "Sizes": [
    "Small",
    "Medium",
    "Large"
  ],
  "Price": 3.99,
  "Expiry": "\/Date(1230447600000-0700)\/",
  "Name": "Apple"
}

Documentation: Serialize an Object

Revalue answered 18/4, 2010 at 4:17 Comment(5)
There's also an example of formatting json output on his blog james.newtonking.com/archive/2008/10/16/…Neolamarckism
@Brad He showed absolutely the same code, but using a modelMetric
So the idea is just Formatting.IndentedChalcis
This method also saves one from making JSON format errors.Prude
This simple method works: private static string GetJson<T> (T json) { return JsonConvert.SerializeObject(json, Formatting.Indented); }Osy
A
241

A shorter sample code for Json.Net library

private static string FormatJson(string json)
{
    dynamic parsedJson = JsonConvert.DeserializeObject(json);
    return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
}
Androsphinx answered 28/1, 2014 at 13:41 Comment(6)
You can actually take this a step further and create an extension method; make it public and change the signature to FormatJson(this string json)Jarboe
There is no need for extensionsBargeman
@HaseeBMir easy to say 6.5 years later, MS did not care about developers that much in the past.Androsphinx
Note: there's no need to cast this a dynamic parsedJson. You can just use var or objectAcquah
@RonSijm object does complain about attributes in certain conditions. dynamic is not necessary but safer.Androsphinx
Seems like this should be the accepted answer.Downpour
S
161

If you have a JSON string and want to "prettify" it, but don't want to serialise it to and from a known C# type then the following does the trick (using JSON.NET):

using System;
using System.IO;
using Newtonsoft.Json;

class JsonUtil
{
    public static string JsonPrettify(string json)
    {
        using (var stringReader = new StringReader(json))
        using (var stringWriter = new StringWriter())
        {
            var jsonReader = new JsonTextReader(stringReader);
            var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented };
            jsonWriter.WriteToken(jsonReader);
            return stringWriter.ToString();
        }
    }
}
Sonneteer answered 19/5, 2015 at 15:20 Comment(4)
For only prettify a Json string this is a much proper solution than the others...Febrifugal
The following use cases will fail: JsonPrettify("null") and JsonPrettify("\"string\"")Reclusion
Thanks @Ekevoo, I've rolled it back to my previous version!Sonneteer
@DuncanSmart I love this! That version creates way fewer temporary objects. I think it it's better than the one I criticized even if those use cases worked.Reclusion
B
142

Shortest version to prettify existing JSON: (edit: using JSON.net)

JToken.Parse("mystring").ToString()

Input:

{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }}

Output:

{
  "menu": {
    "id": "file",
    "value": "File",
    "popup": {
      "menuitem": [
        {
          "value": "New",
          "onclick": "CreateNewDoc()"
        },
        {
          "value": "Open",
          "onclick": "OpenDoc()"
        },
        {
          "value": "Close",
          "onclick": "CloseDoc()"
        }
      ]
    }
  }
}

To pretty-print an object:

JToken.FromObject(myObject).ToString()
Brassy answered 28/11, 2016 at 22:48 Comment(4)
This works even without knowing the structure of the json in advance. And it is the shortest answer here。Prairie
Thanks a lot, man I wasted around 2 hours to get to this solution... Can't imagine my life without @stackoverflow ...Eno
I really prefer this one over the other answers. Short code and effective. Thank youLeftwich
Will not work for: var json = @"{""dateMicrosoft"":""/Date(1526256000000)/""}"; Outputs: { "dateMicrosoft": "2018-05-14T00:00:00Z" } Havent found a way around this.Kristikristian
A
66

Oneliner using Newtonsoft.Json.Linq:

string prettyJson = JToken.Parse(uglyJsonString).ToString(Formatting.Indented);
Atencio answered 22/3, 2018 at 11:3 Comment(3)
I agree this is the simplest API for formatting JSON using NewtonsoftBirdsall
Couldn't find this in Newtonsoft.Json...maybe I have an older version.Laubin
It's in the NewtonSoft.Json.Linq namespace. I only know this because I went searching for it too.Howl
F
59

Net Core App

var js = JsonSerializer.Serialize(obj, new JsonSerializerOptions {
             WriteIndented = true
         });
Feint answered 3/4, 2020 at 3:1 Comment(3)
This answer should have more votes. Is everyone still using the .Net Framework?Taxiway
this answer is respectableCreditable
Best answer here, uses the standard JSON library, no complicated code. Should be the top responseBerkeleianism
B
35

All this can be done in one simple line:

string jsonString = JsonConvert.SerializeObject(yourObject, Formatting.Indented);
Bloodstained answered 18/3, 2020 at 10:21 Comment(2)
Remember to add 'using Newtonsoft.Json'Bloodstained
best answer my friend.Henceforth
D
28

Here is a solution using Microsoft's System.Text.Json library:

static string FormatJsonText(string jsonString)
{
    using var doc = JsonDocument.Parse(
        jsonString,
        new JsonDocumentOptions
        {
            AllowTrailingCommas = true
        }
    );
    MemoryStream memoryStream = new MemoryStream();
    using (
        var utf8JsonWriter = new Utf8JsonWriter(
            memoryStream,
            new JsonWriterOptions
            {
                Indented = true
            }
        )
    )
    {
        doc.WriteTo(utf8JsonWriter);
    }
    return new System.Text.UTF8Encoding()
        .GetString(memoryStream.ToArray());
}
Develop answered 20/2, 2020 at 0:20 Comment(2)
This is a good solution for those who can't purchase an additional package. Works well.Hermetic
Nice one, Didn't want to add an additional package.Wharve
L
28

2023 Update

For those who ask how I get formatted JSON in .NET using C# and want to see how to use it right away and one-line lovers. Here are the indented JSON string one-line codes:

There are 2 well-known JSON formatter or parsers to serialize:

Newtonsoft Json.Net version:

using Newtonsoft.Json;

var jsonString = JsonConvert.SerializeObject(yourObj, Formatting.Indented);

.Net 7 version:

using System.Text.Json;

var jsonString = JsonSerializer.Serialize(yourObj, new JsonSerializerOptions { WriteIndented = true });
Labarum answered 25/11, 2022 at 12:5 Comment(1)
This should be upvoted more.Petrick
V
13

You may use following standard method for getting formatted Json

JsonReaderWriterFactory.CreateJsonWriter(Stream stream, Encoding encoding, bool ownsStream, bool indent, string indentChars)

Only set "indent==true"

Try something like this

    public readonly DataContractJsonSerializerSettings Settings = 
            new DataContractJsonSerializerSettings
            { UseSimpleDictionaryFormat = true };

    public void Keep<TValue>(TValue item, string path)
    {
        try
        {
            using (var stream = File.Open(path, FileMode.Create))
            {
                //var currentCulture = Thread.CurrentThread.CurrentCulture;
                //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
                        stream, Encoding.UTF8, true, true, "  "))
                    {
                        var serializer = new DataContractJsonSerializer(type, Settings);
                        serializer.WriteObject(writer, item);
                        writer.Flush();
                    }
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                }
                finally
                {
                    //Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch (Exception exception)
        {
            Debug.WriteLine(exception.ToString());
        }
    }

Pay your attention to lines

    var currentCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
    ....
    Thread.CurrentThread.CurrentCulture = currentCulture;

For some kinds of xml-serializers you should use InvariantCulture to avoid exception during deserialization on the computers with different Regional settings. For example, invalid format of double or DateTime sometimes cause them.

For deserializing

    public TValue Revive<TValue>(string path, params object[] constructorArgs)
    {
        try
        {
            using (var stream = File.OpenRead(path))
            {
                //var currentCulture = Thread.CurrentThread.CurrentCulture;
                //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    var serializer = new DataContractJsonSerializer(type, Settings);
                    var item = (TValue) serializer.ReadObject(stream);
                    if (Equals(item, null)) throw new Exception();
                    return item;
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                    return (TValue) Activator.CreateInstance(type, constructorArgs);
                }
                finally
                {
                    //Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch
        {
            return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
        }
    }

Thanks!

Vent answered 23/7, 2016 at 5:21 Comment(5)
Hi, @Makeman, have you ever reproduced serialization errors caused by different cultures? Seems like XmlJsonWriter/Reader conversions are all culture invariant.Benzoate
Hello, I am not sure about XmlJsonWriter/Reader, but DataContractJsonSerializer uses Thread.CurrentThread.CurrentCulture. Errors may occur when data have been serialized on the machine A but deserialized on the B with another regional settings.Vent
I decompiled DataContractJsonSerializer in assembly System.Runtime.Serialization v.4.0.0.0, there is no explicit usage of CurrentCulture. The only usage of a culture is CultureInfo.InvariantCulture in the base class XmlObjectSerializer, internal method TryAddLineInfo.Benzoate
So, maybe it is my mistake. I will check it later. Possible, I am extrapolate this culture issue from implementation of an another serializer.Vent
I have edited the original answer. Seems that DataContract serializers are culture independed, but you should save attention to avoid culture specific errors during serialization by another sorts of serializers. :)Vent
C
8

Using System.Text.Json set JsonSerializerOptions.WriteIndented = true:

JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true };
string json = JsonSerializer.Serialize<Type>(object, options);
Christman answered 2/3, 2020 at 14:48 Comment(0)
P
7
using System.Text.Json;
...
var parsedJson = JsonSerializer.Deserialize<ExpandoObject>(json);
var options = new JsonSerializerOptions() { WriteIndented = true };
return JsonSerializer.Serialize(parsedJson, options);
Previdi answered 2/10, 2021 at 2:30 Comment(0)
U
2

First I wanted to add comment under Duncan Smart post, but unfortunately I have not got enough reputation yet to leave comments. So I will try it here.

I just want to warn about side effects.

JsonTextReader internally parses json into typed JTokens and then serialises them back.

For example if your original JSON was

{ "double":0.00002, "date":"\/Date(1198908717056)\/"}

After prettify you get

{ 
    "double":2E-05,
    "date": "2007-12-29T06:11:57.056Z"
}

Of course both json string are equivalent and will deserialize to structurally equal objects, but if you need to preserve original string values, you need to take this into concideration

Uncommon answered 2/2, 2017 at 22:29 Comment(1)
There is a great discussion about this detail here ... github.com/JamesNK/Newtonsoft.Json/issues/862 Interesting how this detail has evolved. I learned something new about my primary json parser - Thank you for your comment.Fractionize
N
1

This worked for me. In case someone is looking for a VB.NET version.

@imports System
@imports System.IO
@imports Newtonsoft.Json
    
Public Shared Function JsonPrettify(ByVal json As String) As String
  Using stringReader = New StringReader(json)

    Using stringWriter = New StringWriter()
      Dim jsonReader = New JsonTextReader(stringReader)
      Dim jsonWriter = New JsonTextWriter(stringWriter) With {
          .Formatting = Formatting.Indented
      }
      jsonWriter.WriteToken(jsonReader)
      Return stringWriter.ToString()
    End Using
  End Using
End Function
Neuter answered 20/2, 2020 at 13:48 Comment(0)
M
1

I have something very simple for this. You can put as input really any object to be converted into json with a format:

private static string GetJson<T> (T json)
{
    return JsonConvert.SerializeObject(json, Formatting.Indented);
}
Meadow answered 24/5, 2021 at 9:22 Comment(0)
W
1

.NET 5 has built in classes for handling JSON parsing, serialization, deserialization under System.Text.Json namespace. Below is an example of a serializer which converts a .NET object to a JSON string,

using System.Text.Json;
using System.Text.Json.Serialization;

private string ConvertJsonString(object obj)
{
    JsonSerializerOptions options = new JsonSerializerOptions();
    options.WriteIndented = true; //Pretty print using indent, white space, new line, etc.
    options.NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals; //Allow NANs
    string jsonString = JsonSerializer.Serialize(obj, options);
    return jsonString;
}
Windle answered 27/8, 2021 at 18:40 Comment(0)
A
0

Below code works for me:

JsonConvert.SerializeObject(JToken.Parse(yourobj.ToString()))
Alphaalphabet answered 7/4, 2020 at 14:4 Comment(0)
A
0

For UTF8 encoded JSON file using .NET Core 3.1, I was finally able to use JsonDocument based upon this information from Microsoft: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to#utf8jsonreader-utf8jsonwriter-and-jsondocument

string allLinesAsOneString = string.Empty;
string [] lines = File.ReadAllLines(filename, Encoding.UTF8);
foreach(var line in lines)
    allLinesAsOneString += line;

JsonDocument jd = JsonDocument.Parse(Encoding.UTF8.GetBytes(allLinesAsOneString));
var writer = new Utf8JsonWriter(Console.OpenStandardOutput(), new JsonWriterOptions
{
    Indented = true
});
JsonElement root = jd.RootElement;
if( root.ValueKind == JsonValueKind.Object )
{
    writer.WriteStartObject();
}
foreach (var jp in root.EnumerateObject())
    jp.WriteTo(writer);
writer.WriteEndObject();

writer.Flush();
Almaalmaata answered 16/7, 2020 at 19:8 Comment(0)
A
0
var formattedJson = System.Text.Json.JsonSerializer.Serialize(myresponse, new JsonSerializerOptions
{
     WriteIndented = true
});
    Console.WriteLine(formattedJson);

enter image description here

Anthracene answered 8/6, 2023 at 14:3 Comment(0)
S
0
using System.Text.Json;

namespace Something.Extensions;

public static class StringExtensions
{    
    static JsonSerializerOptions defaultJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
    public static string FormatJson(this string json, JsonSerializerOptions? options = default) => 
        JsonSerializer.Serialize<object>(JsonSerializer.Deserialize<object>(json ?? "{}")!, options ?? defaultJsonSerializerOptions);
}

usage

var r = @"
    
    {
    ""dsadsa"":""asdasd""
            }";
content = r.FormatJson(new JsonSerializerOptions { WriteIndented = true });

use case example: unknown API response without indented response

var businessId = 2;
var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:7010/Business/{businessId}");
var client = clientFactory.CreateClient();
var responseMessage = await client.SendAsync(request);
if (responseMessage.IsSuccessStatusCode)
{
    var r = await responseMessage.Content.ReadAsStringAsync();
    content = r.FormatJson(new JsonSerializerOptions { WriteIndented = true });
}
else
{
    throw new Exception($"!IsSuccessStatusCode:{responseMessage.StatusCode}");
}
Sweetmeat answered 19/3 at 8:27 Comment(0)
O
0

Serialization in .NET 9 offers more flexibility with customizable JSON output. You can now easily customize indentation characters and their size for more readable JSON files.

var options = new JsonSerializerOptions
{
    WriteIndented = true,
    IndentationSize = 4
};

string jsonString = JsonSerializer.Serialize(yourObject, options);
Orlov answered 31/3 at 20:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.