using System.Collections;
using System.Collections.Generic;
using System.Text.Json.Serialization;
public class NoIndentationConverter : NoIndentationConverter<object>
public override bool CanConvert(Type typeToConvert) => true;
public class NoIndentationConverter<T> : DefaultConverterFactory<T>
protected override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions modifiedOptions)
var bufferWriter = new ArrayBufferWriter<byte>();
using (var innerWriter = new Utf8JsonWriter(bufferWriter))
JsonSerializer.Serialize(innerWriter, value, modifiedOptions);
writer.WriteRawValue(bufferWriter.WrittenSpan, skipInputValidation : true);
protected override JsonSerializerOptions ModifyOptions(JsonSerializerOptions options) { (options = base.ModifyOptions(options)).WriteIndented = false; return options; }
public abstract class DefaultConverterFactory<T> : JsonConverterFactory
class DefaultConverter : JsonConverter<T>
readonly JsonSerializerOptions modifiedOptions;
readonly DefaultConverterFactory<T> factory;
public DefaultConverter(JsonSerializerOptions modifiedOptions, DefaultConverterFactory<T> factory) => (this.modifiedOptions, this.factory) = (modifiedOptions, factory);
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) => factory.Write(writer, value, modifiedOptions);
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => factory.Read(ref reader, typeToConvert, modifiedOptions);
public override bool CanConvert(Type typeToConvert) => typeof(T).IsAssignableFrom(typeToConvert);
protected virtual JsonSerializerOptions ModifyOptions(JsonSerializerOptions options)
=> options.CopyAndRemoveConverter(this.GetType());
protected virtual T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions modifiedOptions)
=> (T?)JsonSerializer.Deserialize(ref reader, typeToConvert, modifiedOptions);
protected virtual void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions modifiedOptions)
=> JsonSerializer.Serialize(writer, value, modifiedOptions);
public override bool CanConvert(Type typeToConvert) => typeof(T) == typeToConvert;
public sealed override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new DefaultConverter(ModifyOptions(options), this);
public static class JsonSerializerExtensions
public static JsonSerializerOptions CopyAndRemoveConverter(this JsonSerializerOptions options, Type converterType)
var copy = new JsonSerializerOptions(options);
for (var i = copy.Converters.Count - 1; i >= 0; i--)
if (copy.Converters[i].GetType() == converterType)
copy.Converters.RemoveAt(i);
public partial class Root
[JsonPropertyName("TILESET")]
public string Tileset { get; set; }
[JsonPropertyName("TILES")]
public Tiles Tiles { get; set; }
public partial class Tiles
[JsonPropertyName("TILE_1")]
public Tile1 Tile1 { get; set; }
public partial class Tile1
[JsonPropertyName("NAME")]
public string Name { get; set; }
[JsonPropertyName("TEXTURE_BOUNDS")]
public List<long> TextureBounds { get; set; }
[JsonPropertyName("SCREEN_BOUNDS")]
public List<long> ScreenBounds { get; set; }
public static void Test()
var originalJson = GetJson();
var options = new JsonSerializerOptions
Converters = { new NoIndentationConverter<List<long>>() },
var root = JsonSerializer.Deserialize<Root>(originalJson, options);
var json2 = JsonSerializer.Serialize(root, options);
Console.WriteLine("Serialized {0}: ", root);
Console.WriteLine(json2);
""TILESET"": ""tilesets/HOW_TO_GET_TILESET_NAME_?"",
""NAME"": ""auto_tile_18"",
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");