Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataContractJsonSerializer human-readable json [duplicate]

Basically a dupe of this question with one notable difference - I have to use DataContractJsonSerializer.

A simple

using (var stream = new MemoryStream())
{
    var serializer = new DataContractJsonSerializer(typeof(Person));
    serializer.WriteObject(stream, obj);
    ...
    return stream.ToArray();
}

produced single line json, e.g. (when saved in file)

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

What are the options to make it

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

I can think of post-processing... Is there an easier option? E.g. similar to formatting xml produced by DataContractSerializer ?

using (var stream = new MemoryStream())
{
    var serializer = new DataContractJsonSerializer(typeof(T));
    // "beautify"
    using (var writer = new SomeKindOfWriter(stream))
        serializer.WriteObject(writer, obj);
    ...
    return stream.ToArray();
}

Is there a way to make such SomeKindOfWriter to beautify json when needed?

like image 522
Sinatr Avatar asked Oct 27 '15 15:10

Sinatr


1 Answers

https://stackoverflow.com/a/38538454/6627992

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!

like image 154
Makeman Avatar answered Sep 23 '22 15:09

Makeman