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?

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

You can even set the desired formatting settings JsonConvert.SerializeObject(message, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
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();
    }

}

4 Comments

Why use IDisposable? Why not just make Process a static method?
@tenfour - you are absolutely correct. This code snippet came from a larger block that got simplified for stackoverflow... I will simplify it further.
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.SerializeObject
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.
21

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();
}

Comments

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.

1 Comment

Link 2 says... Python 2.5 is no longer available.
0

About

public static string FormatOutput(string jsonString):

Thanks a lot - it's useful. Alternatively, to use space, it worked for me: stringBuilder.Append('\t', ... to replace with FormatOutput_NewLine(stringBuilder, ...

private static void FormatOutput_NewLine(StringBuilder stringBuilder, int indentation)
        {
            const string xNEWLINE = "\r\n";
            const string xIndent = "    ";

            stringBuilder.Append(xNEWLINE);
            int i = 0;
            while (i < indentation)
            {
                stringBuilder.Append(xIndent);
                i++;
            }
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.