0

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);
    }
}
nop
  • 4,711
  • 6
  • 32
  • 93
  • 1
    Please read [ask] and explain where you're currently stuck and what you've tried to do to resolve that. It's not clear what exactly you're asking for help with. Should we translate your code for you from Newtonsoft to System.Text.Json? Any particular constructs you need help with? – CodeCaster Nov 29 '21 at 15:19
  • @CodeCaster, I added it to the question and yes I need a translation from `Newtonsoft.Json` to `System.Text.Json` of the whole method, because there is no `JObject` or `.ToObject` methods in `System.Text.Json`. – nop Nov 29 '21 at 15:22
  • [This](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to) might be of use. – SwiftSharp Nov 29 '21 at 15:30
  • Your question is not correct. There is no text json or newtosoft json. Json is the same for any serializer. You have to post the code that is working using newtonsoft library and not working using microsoft naitive library and ask how it could be fixed. – Serge Nov 29 '21 at 15:44
  • @SwiftSharp, I added my attempt, it works, but it's probably not optimal because I'm nohandling JsonDocument's disposal and so. – nop Nov 29 '21 at 21:55
  • @Serge, I added my working attempt for the migration. – nop Nov 29 '21 at 21:56
  • 1
    @nop I posted my answer. Let me know what data you need to extract from json. – Serge Nov 29 '21 at 22:41

1 Answers1

2

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; }
    }
Serge
  • 40,935
  • 4
  • 18
  • 45