'Write List<double> to Json array without indentation using System.Text.Json
NB: I am using System.Text.Json
not JSON.NET
for which there is similar question that has been answered. I need the same answer but for System.Text.Json
. I would like to write my class to Json and ensure that it is human readable. To do this I have set the indent to true in options. However, the class contains a List<double>
property which I don't want to indent as it makes the file very long.
So I have this:
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);
and I want it to serialize like this:
{
"Name": "Example",
"LargeList ": [0,0,0]
}
Not this (or something along these lines):
{
"Name": "Example",
"LargeList ": [
0,
0,
0
]
}
I have written a JsonConverter
to achieve this:
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);
}
}
However this writes the array as a string which I don't really want. Whats the best approach for this?
i.e. you get "[1,2,3]" instead of [1,2,3]
Secondly, the writer
object that is passed into the Write
function has an Options
property but this cannot be changed. So if I write the array out manually using the writer object, it is indented.
Solution 1:[1]
Thanks for your idea, I wrote a wrapper based on the Converter hint
The idea is write a temp value during conversion, put correct array to a temp dict and replace them later
It's a bit late for you but maybe it can help other guys
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 = $"TMP_{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();
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |