将 Newtonsoft.Json 代码迁移到 System.Text.Json

Posted

技术标签:

【中文标题】将 Newtonsoft.Json 代码迁移到 System.Text.Json【英文标题】:Migrating Newtonsoft.Json code to System.Text.Json 【发布时间】:2022-01-06 10:33:25 【问题描述】:

如何将以下方法从Newtonsoft.Json 迁移到System.Text.Json?您可以在下面看到我尝试的方法,但JsonDocument 似乎是一次性的,我想知道是否有更好的解决方案接近JObject,它不会继承IDisposable

响应

"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 方式

下面的代码也可以在下面的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);
    

我的尝试(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);
    

【问题讨论】:

请阅读How to Ask 并说明您目前遇到的问题以及您为解决该问题所做的尝试。目前尚不清楚您究竟在寻求什么帮助。我们应该将您的代码从 Newtonsoft 翻译成 System.Text.Json 吗?您需要帮助的任何特定构造? @CodeCaster,我将它添加到问题中,是的,我需要将整个方法从Newtonsoft.Json 翻译为System.Text.Json,因为@ 中没有JObject.ToObject 方法987654338@. This 可能有用。 您的问题不正确。没有文本 json 或 newtosoft json。 Json 对于任何序列化程序都是相同的。您必须发布使用 newtonsoft 库而不使用 microsoft naitive 库的代码,并询问如何修复它。 @nop 我发布了我的答案。让我知道您需要从 json 中提取哪些数据。 【参考方案1】:

我不明白你想达到什么,但我是这样反序列化的 使用 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;

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; 
    

【讨论】:

以上是关于将 Newtonsoft.Json 代码迁移到 System.Text.Json的主要内容,如果未能解决你的问题,请参考以下文章

无法将类型为“Newtonsoft.Json.Linq.JObject”的对象转换为类型“System.Collections.Generic.Dictionary`2[System.String,S

Newtonsoft.Json过滤输出[重复]

使用 Newtonsoft.JSON 在 C# 中的泛型方法中的 DeserializeObject<T>(string s) 不起作用

从 JSON 检索项目时获取“无法将 Newtonsoft.Json.Linq.JObject 转换为 Newtonsoft.Json.Linq.JToken”

JsonConverter 等效于使用 System.Text.Json

Newtonsoft.Json v11 - DeserializeObject抛出JsonReaderException