【问题标题】:Write List<double> to Json array without indentation using System.Text.Json使用 System.Text.Json 将 List<double> 写入 Json 数组而不缩进
【发布时间】:2019-10-15 13:04:02
【问题描述】:

注意:我使用的是System.Text.Json 而不是JSON.NET,对此有类似的问题已得到解答。我需要相同的答案,但对于System.Text.Json。我想将我的课程写成 Json 并确保它是人类可读的。为此,我在选项中将缩进设置为 true。但是,该类包含一个List&lt;double&gt; 属性,我不想缩进它,因为它使文件很长。

所以我有这个:

public class ThingToSerialize
{
    public string Name {get;set;}
    //other properties here
    public List<double> LargeList {get;set;}
};

var thing = new ThingToSerialize {Name = "Example", LargeList = new List<double>{0,0,0}};
var options = new JsonSerializerOptions
{
    WriteIndented = true
};

options.Converters.Add(new DontIndentArraysConverter());

var s = JsonSerializer.Serialize(thing, options);

我希望它像这样序列化:

{
    "Name": "Example",
    "LargeList ": [0,0,0]
}

不是这个(或类似的东西):

{
    "Name": "Example",
    "LargeList ": [
        0,
        0,
        0
    ]
}

我写了一个JsonConverter 来实现这个:

public class DontIndentArraysConverter  : JsonConverter<List<double>>
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<double>);
    }

    public override List<double> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return JsonSerializer.Deserialize<List<double>>(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, List<double> value, JsonSerializerOptions options)
    {
        var s = JsonSerializer.Serialize(value);
        writer.WriteStringValue(s);
    }

}

但是,这会将数组写入我并不真正想要的字符串。最好的方法是什么?

即你得到“[1,2,3]”而不是[1,2,3]

其次,传递给Write 函数的writer 对象具有Options 属性,但不能更改。因此,如果我使用 writer 对象手动写出数组,它会缩进。

【问题讨论】:

  • 以上使用的是 Json.Net 而不是 System.Text.Json 所以这不是重复的
  • 我的答案是放弃 System.Text.Json 并使用 Json.Net。
  • JsonSerializer.Serialize(writer, value, new JsonSerializerOptions() { WriteIndented = false }); 应该可以工作,但不能。 :(

标签: c# json system.text.json jsonconverter


【解决方案1】:

感谢您的想法,我根据转换器提示编写了自己的序列化程序

想法是在转换过程中写入一个临时值,将正确的数组放入临时字典并稍后替换它们

对你来说有点晚了,但也许它可以帮助其他人

public class CustomSerializer : IDisposable
{
    private readonly Dictionary<string, string> _replacement = new Dictionary<string, string>();

    public string Serialize<T>(T obj)
    {
        var converterForListInt = new DontIndentArraysConverterForListInt(_replacement);

        var options = new JsonSerializerOptions
        {
            IgnoreNullValues = true,
            WriteIndented = true
        };
        
        options.Converters.Add(converterForListInt);

        var json = JsonSerializer.Serialize(obj, options);
        foreach (var (k, v) in _replacement)
            json = json.Replace(k, v);
        return json;
    }

    public void Dispose()
    {
        _replacement.Clear();
    }
    
    public class DontIndentArraysConverterForListInt  : JsonConverter<List<int>>
    {
        private readonly Dictionary<string, string> _replacement;

        public DontIndentArraysConverterForListInt(Dictionary<string, string> replacement)
        {
            _replacement = replacement;
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(List<int>);
        }

        public override List<int> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return JsonSerializer.Deserialize<List<int>>(reader.GetString());
        }

        public override void Write(Utf8JsonWriter writer, List<int> value, JsonSerializerOptions options)
        {
            if (value.Count > 0)
            {
                var key = $"TEMPLATE_{Guid.NewGuid().ToString()}";
                var sb = new StringBuilder();
                sb.Append('[');
                foreach (var i in value)
                {
                    sb.Append(i);
                    sb.Append(',');
                }
                sb.Remove(sb.Length - 1, 1); // trim last ,
                sb.Append(']');
                _replacement.Add($"\"{key}\"", sb.ToString());
                
                //
                writer.WriteStringValue(key);
            }
            else
            {
                // normal
                writer.WriteStartArray();
                writer.WriteEndArray();
            }
        }
    }
}

【讨论】:

  • 感谢您的回答,我的结论是 json.net 是要走的路,但希望有人会觉得这很有用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-06
  • 2010-11-27
相关资源
最近更新 更多