0

I've searched for a simple native way to beautify a JSON in C# and have fond none, so I did my own and share it here, hope it helps ;)

It transforms condensed JSON like this:

[{"level":1,"exp":110,"energyGranted":5,"itemGranted":null},{"level":2,"exp":195,"energyGranted":5,"itemGranted":null},{"level":3,"exp":296,"energyGranted":5,"itemGranted":null}]

To nice formated JSON like this:

[
    {
        "level": 1,
        "exp": 110,
        "energyGranted": 5,
        "itemGranted": null
    },
    {
        "level": 2,
        "exp": 195,
        "energyGranted": 5,
        "itemGranted": null
    },
    {
        "level": 3,
        "exp": 296,
        "energyGranted": 5,
        "itemGranted": null
    }
]

Context : I was working on a Unity project that handles JSON responses I get from a backend. I didn't want to append some third party C# library just for that simple task. There is the JsonUtility.ToJson(obj, prettyPrint) Unity built-in method doing that but only from an object, not a JSON, thus my need.

Thomas LAURENT
  • 1,592
  • 1
  • 11
  • 9
  • Does this answer your question? [JSON formatter in C#?](https://stackoverflow.com/questions/4580397/json-formatter-in-c) –  Jan 10 '20 at 20:14
  • I missed this one :s I googled "beautify" not "format" that's why ^^ My answer is shorter than the accepted one in the post you linked but it also has good alternatives like this underrated one : https://stackoverflow.com/a/57100143/4052438 Thanks for the link and your time! – Thomas LAURENT Jan 11 '20 at 10:36

2 Answers2

0

So here is my solution, it uses Regex groups to split the JSON in multiple lines and depending on the group modifies the indent.

To avoid complicating the regex I'm not dealing with spaces, so it expects a condensed JSON.

using System.Text; // used for StringBuilder, a better string concatenation than myStr += "content"
using System.Text.RegularExpressions;

public static class JsonUtil
{
    public static string Beautify(string json)
    {
        const int indentWidth = 4;
        const string pattern = "(?>([{\\[][}\\]],?)|([{\\[])|([}\\]],?)|([^{}:]+:)([^{}\\[\\],]*(?>([{\\[])|,)?)|([^{}\\[\\],]+,?))";

        var match = Regex.Match(json, pattern);
        var beautified = new StringBuilder();
        var indent = 0;
        while (match.Success)
        {
            if (match.Groups[3].Length > 0)
                indent--;

            beautified.AppendLine(
                new string(' ', indent * indentWidth) +
                (match.Groups[4].Length > 0
                    ? match.Groups[4].Value + " " + match.Groups[5].Value
                    : (match.Groups[7].Length > 0 ? match.Groups[7].Value : match.Value))
            );

            if (match.Groups[2].Length > 0 || match.Groups[6].Length > 0)
                indent++;

            match = match.NextMatch();
        }

        return beautified.ToString();
    }
}

To use it: var beautifiedJson = JsonUtil.Beautify(json);

It may not be the best solution in terms of performance but it worked perfectly for my use ^^

If you have a better one please take the time to share it ;)

Thomas LAURENT
  • 1,592
  • 1
  • 11
  • 9
0

Have you tried converting your string to object then then use ToJson function?

var myObj = JsonUtility.FromJson<YourClass>(jsonString);
var prettyString = JsonUtility.ToJson(myObj);
Nishant
  • 1
  • 1
  • In my context I don't know what's in `YourClass` because I don't know what is in my JSON: it's returned from a backend I'm testing. Also your solution implies to create this class which is a bit overkill to just format a JSON if you have like plenty of different JSON structures like in my case. – Thomas LAURENT Jan 11 '20 at 10:22