How to set formatting with JavaScriptSerializer when JSON serializing?
Asked Answered
I

4

27

I am using JavaScriptSerializer for serializing objects to the file to the JSON format. But the result file has no readable formatting. How can I allow formating to get a readable file?

Infirm answered 4/5, 2011 at 9:18 Comment(0)
E
13

It seemed to be that there is no built-in tool for formatting JSON-serializer's output.
I suppose the reason why this happened is minimizing of data that we send via network.

Are you sure that you need formatted data in code? Or you want to analize JSON just during debugging?

There is a lot of online services that provide such functionality: 1, 2. Or standalone application: JSON viewer.

But if you need formatting inside application, you can write appropriate code by yourself.

Exaggeration answered 4/5, 2011 at 9:46 Comment(1)
Link 2 says... Python 2.5 is no longer available.Sheronsherourd
S
34

You could use JSON.NET serializer, it supports JSON formatting

string body = JsonConvert.SerializeObject(message, Formatting.Indented);

Yon can download this package via NuGet.

Sirrah answered 4/5, 2011 at 12:22 Comment(1)
You can even set the desired formatting settings JsonConvert.SerializeObject(message, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });Holdback
G
24

Here's my solution that does not require using JSON.NET and is simpler than the code linked by Alex Zhevzhik.

    using System.Web.Script.Serialization; 
    // add a reference to System.Web.Extensions


    public void WriteToFile(string path)
    {
        var serializer     = new JavaScriptSerializer();
        string json        = serializer.Serialize(this);
        string json_pretty = JSON_PrettyPrinter.Process(json);
        File.WriteAllText(path, json_pretty );
    }

and here is the formatter

class JSON_PrettyPrinter
{
    public static string Process(string inputText)
    {
        bool escaped = false;
        bool inquotes = false;
        int column = 0;
        int indentation = 0;
        Stack<int> indentations = new Stack<int>();
        int TABBING = 8;
        StringBuilder sb = new StringBuilder();
        foreach (char x in inputText)
        {
            sb.Append(x);
            column++;
            if (escaped)
            {
                escaped = false;
            }
            else
            {
                if (x == '\\')
                {
                    escaped = true;
                }
                else if (x == '\"')
                {
                    inquotes = !inquotes;
                }
                else if ( !inquotes)
                {
                    if (x == ',')
                    {
                        // if we see a comma, go to next line, and indent to the same depth
                        sb.Append("\r\n");
                        column = 0;
                        for (int i = 0; i < indentation; i++)
                        {
                            sb.Append(" ");
                            column++;
                        }
                    } else if (x == '[' || x== '{') {
                        // if we open a bracket or brace, indent further (push on stack)
                        indentations.Push(indentation);
                        indentation = column;
                    }
                    else if (x == ']' || x == '}')
                    {
                        // if we close a bracket or brace, undo one level of indent (pop)
                        indentation = indentations.Pop();
                    }
                    else if (x == ':')
                    {
                        // if we see a colon, add spaces until we get to the next
                        // tab stop, but without using tab characters!
                        while ((column % TABBING) != 0)
                        {
                            sb.Append(' ');
                            column++;
                        }
                    }
                }
            }
        }
        return sb.ToString();
    }

}
Gomuti answered 6/11, 2012 at 22:2 Comment(4)
Why use IDisposable? Why not just make Process a static method?Hipolitohipp
@Hipolitohipp - you are absolutely correct. This code snippet came from a larger block that got simplified for stackoverflow... I will simplify it further.Gomuti
It is not a solution for everybody! You would have page image(or format) conflicts if your project is a .NET 4 or if your project is not a web designation! Notice that you are using System.Web.Extensions (need .NET4.5!) to bring in System.Web.Script.Serialization!! For a concrete solution, you should use NuGet to acquire Newtonsoft and use JsonConvert.SerializeObjectIambus
The code would be significantly simpler and more elegant if you did use tab characters - incidentally, exactly for the purpose they are meant to be.Zischke
P
20

I also wanted to be able to have formatted JSON without relying on a third-party component. Mark Lakata's solution worked well (thanks Mark), but I wanted the brackets and tabbing to be like those in Alex Zhevzhik's link. So here's a tweaked version of Mark's code that works that way, in case anyone else wants it:

/// <summary>
/// Adds indentation and line breaks to output of JavaScriptSerializer
/// </summary>
public static string FormatOutput(string jsonString)
{
    var stringBuilder = new StringBuilder();

    bool escaping = false;
    bool inQuotes = false;
    int indentation = 0;

    foreach (char character in jsonString)
    {
        if (escaping)
        {
            escaping = false;
            stringBuilder.Append(character);
        }
        else
        {
            if (character == '\\')
            {
                escaping = true;
                stringBuilder.Append(character);
            }
            else if (character == '\"')
            {
                inQuotes = !inQuotes;
                stringBuilder.Append(character);
            }
            else if (!inQuotes)
            {
                if (character == ',')
                {
                    stringBuilder.Append(character);
                    stringBuilder.Append("\r\n");
                    stringBuilder.Append('\t', indentation);
                }
                else if (character == '[' || character == '{')
                {
                    stringBuilder.Append(character);
                    stringBuilder.Append("\r\n");
                    stringBuilder.Append('\t', ++indentation);
                }
                else if (character == ']' || character == '}')
                {
                    stringBuilder.Append("\r\n");
                    stringBuilder.Append('\t', --indentation);
                    stringBuilder.Append(character);
                }
                else if (character == ':')
                {
                    stringBuilder.Append(character);
                    stringBuilder.Append('\t');
                }
                else if (!Char.IsWhiteSpace(character))
                {
                    stringBuilder.Append(character);
                }
            }
            else
            {
                stringBuilder.Append(character);
            }
        }
    }

    return stringBuilder.ToString();
}
Plumley answered 23/5, 2014 at 12:9 Comment(0)
E
13

It seemed to be that there is no built-in tool for formatting JSON-serializer's output.
I suppose the reason why this happened is minimizing of data that we send via network.

Are you sure that you need formatted data in code? Or you want to analize JSON just during debugging?

There is a lot of online services that provide such functionality: 1, 2. Or standalone application: JSON viewer.

But if you need formatting inside application, you can write appropriate code by yourself.

Exaggeration answered 4/5, 2011 at 9:46 Comment(1)
Link 2 says... Python 2.5 is no longer available.Sheronsherourd

© 2022 - 2024 — McMap. All rights reserved.