using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class JsonPlainArrayIndexAttribute : Attribute
public JsonPlainArrayIndexAttribute(int index)
public sealed class JsonPlainArrayConverter<T> : JsonConverter<T> where T : new()
ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
Debug.Assert(typeof(T) == typeToConvert);
var props = typeToConvert.GetProperties();
var linq = from prop in props
let attr = prop.GetCustomAttributes(typeof(JsonPlainArrayIndexAttribute), true)
where prop.CanWrite && attr.Length is 1
orderby ((JsonPlainArrayIndexAttribute)attr[0]).Index
var arr = JsonSerializer.Deserialize<IEnumerable<JsonElement>>(ref reader, options);
foreach (var (prop, value) in linq.Zip(arr))
prop.SetValue(result, value.Deserialize(prop.PropertyType, options));
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
var props = type.GetProperties();
var linq = from prop in props
let attr = prop.GetCustomAttributes(typeof(JsonPlainArrayIndexAttribute), true)
where prop.CanRead && attr.Length is 1
orderby ((JsonPlainArrayIndexAttribute)attr[0]).Index
select prop.GetValue(value);
JsonSerializer.Serialize<IEnumerable<object>>(writer, linq, options);
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
[property: JsonPropertyName("pair")] string Pair,
[property: JsonPropertyName("sequence")] long Sequence,
[property: JsonPropertyName("asks")] List<BookLevel> Asks,
[property: JsonPropertyName("bids")] List<BookLevel> Bids,
[property: JsonPropertyName("prev_sequence")] long PreviousSequence
[EnumMember(Value = "snapshot")]
[EnumMember(Value = "update")]
[JsonConverter(typeof(JsonPlainArrayConverter<BookLevel>))]
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public string Price { get; init; }
public string Quantity { get; init; }
public record Changes(string Side, decimal Price, decimal Quantity);
public static void Test()
var options = new JsonSerializerOptions
PropertyNameCaseInsensitive = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString,
var model = JsonSerializer.Deserialize<Depth>(json, options);
static string GetJson() => @"{
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: ");