Home > Blockchain >  Migrating Newtonsoft.Json code to System.Text.Json
Migrating Newtonsoft.Json code to System.Text.Json

Time:11-30

How do I migrate the following method from Newtonsoft.Json to System.Text.Json? You can see what I tried below, but JsonDocument seems to be disposable and I wonder if there is a better solution close to JObject, which doesn't inherit IDisposable.

Response

{"stream":"btcusdt@kline_1m","data":{"e":"kline","E":1638222442946,"s":"BTCUSDT","k":{"t":1638222420000,"T":1638222479999,"s":"BTCUSDT","i":"1m","f":1167943431,"L":1167943801,"o":"58152.63000000","c":"58182.88000000","h":"58188.89000000","l":"58151.94000000","v":"13.01577000","n":371,"x":false,"q":"757188.21010260","V":"6.42902000","Q":"373973.65440090","B":"0"}}}

Newtonsoft.Json way

The code below can also be found on the following GitHub.

public class KlineResponse : ResponseBase<Kline>
{
    internal static bool TryHandle(JObject response, ISubject<KlineResponse> subject)
    {
        var stream = response?["stream"]?.Value<string>();
        if (stream == null)
        {
            return false;
        }

        if (!stream.Contains("kline"))
        {
            return false;
        }

        var parsed = response.ToObject<KlineResponse>(BinanceJsonSerializer.Serializer);
        subject.OnNext(parsed);

        return true;
    }
}

/// <summary>
/// Binance preconfigured JSON serializer
/// </summary>
public static class BinanceJsonSerializer
{
    /// <summary>
    /// JSON settings
    /// </summary>
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
        Formatting = Formatting.None,
        Converters = new List<JsonConverter>()
        {
            new BinanceStringEnumConverter { CamelCaseText = true},
        }
    };

    /// <summary>
    /// Serializer instance
    /// </summary>
    public static readonly JsonSerializer Serializer = JsonSerializer.Create(Settings);

    /// <summary>
    /// Deserialize string into object
    /// </summary>
    public static T Deserialize<T>(string data)
    {
        return JsonConvert.DeserializeObject<T>(data, Settings);
    }

    /// <summary>
    /// Serialize object into JSON string
    /// </summary>
    public static string Serialize(object data)
    {
        return JsonConvert.SerializeObject(data, Settings);
    }
}

My attempt (System.Text.Json)

private bool HandleObjectMessage(string msg)
{
    var response = BinanceJsonSerializer.Deserialize<JsonDocument>(msg);
    return KlineResponse.TryHandle(response, Streams.KlineSubject);
}
public class KlineResponse : ResponseBase<Kline>
{
    internal static bool TryHandle(JsonDocument response, ISubject<KlineResponse> subject)
    {
        var stream = response.RootElement.GetProperty("stream").GetString() ?? string.Empty;

        if (!stream.Contains("kline"))
            return false;

        var parsed =
            response.Deserialize<KlineResponse>(
                new JsonSerializerOptions
                {
                    NumberHandling = JsonNumberHandling.AllowReadingFromString
                });

        subject.OnNext(parsed);

        return true;
    }
}
/// <summary>
///     Binance preconfigured JSON serializer.
/// </summary>
public static class BinanceJsonSerializer
{
    /// <summary>
    ///     JSON settings.
    /// </summary>
    public static readonly JsonSerializerOptions Options = new()
    {
        NumberHandling = JsonNumberHandling.AllowReadingFromString
    };

    /// <summary>
    ///     Deserializes a string into an object.
    /// </summary>
    public static TValue? Deserialize<TValue>(string json)
    {
        return JsonSerializer.Deserialize<TValue>(json, Options);
    }

    /// <summary>
    ///     Serializes an object into a JSON string.
    /// </summary>
    public static string Serialize(object value)
    {
        return JsonSerializer.Serialize(value, Options);
    }
}

CodePudding user response:

I don' t understand what are you trying to reach but I deserialized it this way using System.Text.Json.

var jsonElement =  JsonDocument.Parse(json);
var data = jsonElement.RootElement.GetProperty("data");

//or

var data = System.Text.Json.JsonSerializer.Deserialize<Data>(json).DataData;

classes

public partial class Data
    {
        [JsonPropertyName("stream")]
        public string Stream { get; set; }

        [JsonPropertyName("data")]
        public DataClass DataData { get; set; }
    }

    public partial class DataClass
    {
        [JsonPropertyName("e")]
        public string DataE { get; set; }

        [JsonPropertyName("E")]
        public long E { get; set; }

        [JsonPropertyName("s")]
        public string S { get; set; }

        [JsonPropertyName("k")]
        public K K { get; set; }
    }

    public partial class K
    {
        [JsonPropertyName("t")]
        public long KT { get; set; }

        [JsonPropertyName("T")]
        public long T { get; set; }

        [JsonPropertyName("s")]
        public string S { get; set; }

        [JsonPropertyName("i")]
        public string I { get; set; }

        [JsonPropertyName("f")]
        public long F { get; set; }

        [JsonPropertyName("L")]
        public long L { get; set; }

        [JsonPropertyName("o")]
        public string O { get; set; }

        [JsonPropertyName("c")]
        public string C { get; set; }

        [JsonPropertyName("h")]
        public string H { get; set; }

        [JsonPropertyName("l")]
        public string KL { get; set; }

        [JsonPropertyName("v")]
        public string KV { get; set; }

        [JsonPropertyName("n")]
        public long N { get; set; }

        [JsonPropertyName("x")]
        public bool X { get; set; }

        [JsonPropertyName("q")]
        public string KQ { get; set; }

        [JsonPropertyName("V")]
        public string V { get; set; }

        [JsonPropertyName("Q")]
        public string Q { get; set; }

        [JsonPropertyName("B")]
        public string B { get; set; }
    }
  • Related