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?

dbc
  • 104,963
  • 20
  • 228
  • 340
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • I'm not sure you can do it with `DataContractJsonSerializer` without some external function/library to do it. – DavidG Oct 27 '15 at 15:16
  • 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`](http://stackoverflow.com/a/739169/1997232) if that is possible. – Sinatr Oct 27 '15 at 15:21
  • Are you forces to use exactly type DataContractJsonSerializer? Can it be another class derived from XmlObjectSerializer? – Timur Mannapov Oct 27 '15 at 16:11
  • 3
    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. – Veverke Jul 01 '18 at 14:13
  • @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](https://stackoverflow.com/a/21407175/1997232) is the solution I am using now. – Sinatr Jul 02 '18 at 07:55
  • @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) – Veverke Jul 02 '18 at 07:58

1 Answers1

10

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!

Makeman
  • 884
  • 9
  • 16