在 .net core 3 中将 newtonsoft 代码转换为 System.Text.Json。相当于 JObject.Parse 和 JsonProperty

Posted

技术标签:

【中文标题】在 .net core 3 中将 newtonsoft 代码转换为 System.Text.Json。相当于 JObject.Parse 和 JsonProperty【英文标题】:Converting newtonsoft code to System.Text.Json in .net core 3. what's equivalent of JObject.Parse and JsonProperty 【发布时间】:2019-10-07 14:42:18 【问题描述】:

我正在将我的 newtonsoft 实现转换为 .net core 3.0 中的新 JSON 库。我有以下代码

public static bool IsValidJson(string json)

    try
                    
        JObject.Parse(json);
        return true;
    
    catch (Exception ex)
    
        Logger.ErrorFormat("Invalid Json Received 0", json);
        Logger.Fatal(ex.Message);
        return false;
    

我找不到 JObject.Parse(json); 的任何等效项

还有 JsonProperty 等效属性是什么

public class ResponseJson

    [JsonProperty(PropertyName = "status")]
    public bool Status  get; set; 
    [JsonProperty(PropertyName = "message")]
    public string Message  get; set; 
    [JsonProperty(PropertyName = "Log_id")]
    public string LogId  get; set; 
    [JsonProperty(PropertyName = "Log_status")]
    public string LogStatus  get; set; 

    public string FailureReason  get; set; 

我将寻找与Formating.None 等效的另一件事。

【问题讨论】:

我所理解的是对于简单级别的 json,它真的很简单。对于我们使用一些嵌套 json、一些时间格式、默认值、字典直接 json 创建等的东西。我们必须小心并进行适当的单元测试以比较转换前后的结果 【参考方案1】:

你在这里问了几个问题:

    我找不到 JObject.Parse(json); 的任何等效项

    您可以使用JsonDocument 到parse 并检查任何JSON,从它的RootElement 开始。根元素的类型为JsonElement,它代表任何JSON 值(原始或非原始值)并且对应于Newtonsoft 的JToken

    但请注意此文档remark:

    此类利用池化内存中的资源来最大程度地减少垃圾收集器 (GC) 在高使用情况下的影响。未能正确处置此对象将导致内存未返回到池中,这将增加对框架各个部分的 GC 影响。

    当您需要在其文档的生命周期之外使用JsonElement 时,您必须clone 它:

    获取一个JsonElement,可以在原始JsonDocument 的生命周期之后安全存储。

    另请注意,JsonDocument 当前为 read-only,并且不提供用于创建或修改 JSON 的 API。有一个未解决的问题 Issue #39922: Writable Json DOM 正在跟踪此问题。

    使用示例如下:

    //https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#using-declarations 
    using var doc = JsonDocument.Parse(json);
    
    //Print the property names.
    var names = doc.RootElement.EnumerateObject().Select(p => p.Name);
    Console.WriteLine("Property names: 0", string.Join(",", names)); // Property names: status,message,Log_id,Log_status,FailureReason
    
    //Re-serialize with indentation.
    using var ms = new MemoryStream();
    using (var writer = new Utf8JsonWriter(ms, new JsonWriterOptions  Indented = true ))
    
        doc.WriteTo(writer);
    
    var json2 = Encoding.UTF8.GetString(ms.GetBuffer(), 0, checked((int)ms.Length));
    
    Console.WriteLine(json2);
    

    JsonProperty 等价的属性是什么?

    可以控制JsonSerializer 的属性被放置在System.Text.Json.Serialization 命名空间中,并继承自抽象基类JsonAttribute。与JsonProperty 不同,没有综合属性可以控制属性序列化的所有方面。相反,有特定的属性来控制特定的方面。

    从 .NET Core 3 开始,这些包括:

    [JsonPropertyNameAttribute(string)]:

    指定在序列化和反序列化时出现在 JSON 中的属性名称。这会覆盖JsonNamingPolicy 指定的任何命名策略。

    这是您要用来控制ResponseJson 类的序列化名称的属性:

    public class ResponseJson
    
        [JsonPropertyName("status")]
        public bool Status  get; set; 
        [JsonPropertyName("message")]
        public string Message  get; set; 
        [JsonPropertyName("Log_id")]
        public string LogId  get; set; 
        [JsonPropertyName("Log_status")]
        public string LogStatus  get; set; 
    
        public string FailureReason  get; set; 
    
    

    [JsonConverterAttribute(Type)]:

    当放置在一个类型上时,将使用指定的转换器,除非将兼容的转换器添加到 JsonSerializerOptions.Converters 集合中或在同一类型的属性上存在另一个 JsonConverterAttribute

    注意documented priority of converters -- 属性上的属性,然后是选项中的转换器集合,然后是类型上的属性 -- 与Newtonsoft converters 的记录顺序不同,即 由成员上的属性定义的 JsonConverter,然后是由类上的属性定义的 JsonConverter,最后是传递给 JsonSerializer 的任何转换器。

    [JsonExtensionDataAttribute] - 对应于 Newtonsoft 的 [JsonExtensionData]

    [JsonIgnoreAttribute] - 对应于 Newtonsoft 的 [JsonIgnore]

    通过Utf8JsonWriter编写JSON时,可以通过将JsonWriterOptions.Indented设置为truefalse来控制缩进。

    通过JsonSerializer.Serialize 序列化为JSON 时,可以通过将JsonSerializerOptions.WriteIndented 设置为truefalse 来控制缩进。

演示小提琴here 显示使用JsonSerializer 进行序列化并使用JsonDocument 进行解析。

【讨论】:

谢谢@dbc。看起来 JsonDocument.Parse 对 JObject 和 JsonPropertyName 对我有用。明天将转换我的申请并检查。还有一件事我会寻找相当于 Formatting.None 谢谢【参考方案2】:

这个链接应该可以帮助你,我在下面复制了它的 sn-ps。

https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/

WeatherForecast Deserialize(string json) var options = new JsonSerializerOptions AllowTrailingCommas = true ; return JsonSerializer.Parse<WeatherForecast>(json, options); class WeatherForecast public DateTimeOffset Date get; set; // Always in Celsius. [JsonPropertyName("temp")] public int TemperatureC get; set; public string Summary get; set; // Don't serialize this property. [JsonIgnore] public bool IsHot => TemperatureC >= 30;

【讨论】:

以上是关于在 .net core 3 中将 newtonsoft 代码转换为 System.Text.Json。相当于 JObject.Parse 和 JsonProperty的主要内容,如果未能解决你的问题,请参考以下文章

在 .net core 3 中将 newtonsoft 代码转换为 System.Text.Json。相当于 JObject.Parse 和 JsonProperty

如何在 Visual Studio 中将 .NET Framework 更改为 .NET Standard/Core?

在 .NET Core 中将应用设置与环境变量合并

在 ASP.net Core 中将对象转换为 Json

在 ASP.NET Core 中将 html 导出为 pdf

在 VSCode 中将 SpecFlow 测试添加到 .NET Core 项目