DataContractJsonSerializer人类可读的json

时间:2015-10-27 15:10:24

标签: c# json datacontractjsonserializer

基本上是this问题的重复,但有一个显着的区别 - 我必须使用DataContractJsonSerializer

一个简单的

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

产生单线json,例如(保存在文件中时)

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

有什么选择

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

我可以想到后期处理......有更简单的选择吗?例如。类似于格式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();
}

有没有办法让这种SomeKindOfWriter在需要时美化json?

1 个答案:

答案 0 :(得分:3)

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

您可以使用以下标准方法获取格式化的Json

JsonReaderWriterFactory.CreateJsonWriter(Stream stream,Encoding encoding,bool ownsStream,bool indent,string indentChars)

仅设置"缩进== true"

尝试这样的事情

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

注意线条

    var currentCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
    ....
    Thread.CurrentThread.CurrentCulture = currentCulture;

您应该使用 InvariantCulture 来避免在具有不同区域设置的计算机上进行反序列化时出现异常。例如, double DateTime 的无效格式有时会导致它们。

用于反序列化

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

谢谢!