DataContractJsonSerializer human-readable json [duplicate]
Asked Answered
X

1

11

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?

Xerxes answered 27/10, 2015 at 15:10 Comment(6)
I'm not sure you can do it with DataContractJsonSerializer without some external function/library to do it.Fugleman
Well, I can do post-processing right now, but it sounds stupid: parsing json back (in some way). I'd be happy with answer where there is something in-between of memory stream and json getting values and being able to format them. Similar to XmlWriter if that is possible.Xerxes
Are you forces to use exactly type DataContractJsonSerializer? Can it be another class derived from XmlObjectSerializer?Ganesa
This post is wrongly marked as a duplicate. The post this is being linked to does not show how to achieve a user-readable format using DataContractJsonSerializerSettings, which is THE question being asked here.Atronna
@Veverke, right. But there were other issues and I ended up using json.net, so disregards I mentioned duplicate myself in question when someone see its this way I don't mind. This is the solution I am using now.Xerxes
@Sinatr: at least give the guy below an upvote, he's the one who tackled the original problem, as far as I understand :) (and the one who helped me, after ending up in this post for the problem exacted by the post's title)Atronna
P
10

https://mcmap.net/q/92269/-how-do-i-get-formatted-json-in-net-using-c

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!

Physic answered 24/7, 2016 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.