将Newtonsoft代码转换为在.NET Core 3中使用的System.Text.Json,JObject.Parse和JsonProperty的等效方法是什么?

23
我正在将我的Newtonsoft实现转换为.NET Core 3.0中的新JSON库。 我有以下代码。

我正在将我的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创建等内容的情况,我们必须小心并进行适当的单元测试,以便在转换前后比较结果。 - Kamran Shahid
2个回答

28

您在这里提出了一些问题:

  1. I am not able to find any equivalent for JObject.Parse(json);

    You can use JsonDocument to parse and examine any JSON, starting with its RootElement. The root element is of type JsonElement which represents any JSON value (primitive or not) and corresponds to Newtonsoft's JToken.

    But do take note of this documentation remark:

    This class utilizes resources from pooled memory to minimize the impact of the garbage collector (GC) in high-usage scenarios. Failure to properly dispose this object will result in the memory not being returned to the pool, which will increase GC impact across various parts of the framework.

    When you need to use a JsonElement outside the lifetime of its document, you must clone it:

    Gets a JsonElement that can be safely stored beyond the lifetime of the original JsonDocument.

    Also note that JsonDocument is currently read-only and does not provide an API for creating or modifying JSON. There is an open issue Issue #39922: Writable Json DOM tracking this.

    An example of use is as follows:

    //https://learn.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);
    
  2. Also what will be the attribute JsonProperty equivalent?

    Attributes that can control JsonSerializer are placed in the System.Text.Json.Serialization namespace and inherit from an abstract base class JsonAttribute. Unlike JsonProperty, there is no omnibus attribute that can control all aspects of property serialization. Instead there are specific attributes to control specific aspects.

    As of .NET Core 3 these include:

    • [JsonPropertyNameAttribute(string)]:

      Specifies the property name that is present in the JSON when serializing and deserializing. This overrides any naming policy specified by JsonNamingPolicy.

      This is attribute you want to use to control the serialized names of your ResponseJson class:

      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)]:

      When placed on a type, the specified converter will be used unless a compatible converter is added to the JsonSerializerOptions.Converters collection or there is another JsonConverterAttribute on a property of the same type.

      Note that the documented priority of converters -- Attribute on property, then the Converters collection in options, then the Attribute on type -- differs from the documented order for Newtonsoft converters, which is the JsonConverter defined by attribute on a member, then the JsonConverter defined by an attribute on a class, and finally any converters passed to the JsonSerializer.

    • [JsonExtensionDataAttribute] - corresponds to Newtonsoft's [JsonExtensionData].

    • [JsonIgnoreAttribute] - corresponds to Newtonsoft's [JsonIgnore].

  3. When writing JSON via Utf8JsonWriter, indentation can be controlled by setting JsonWriterOptions.Indented to true or false.

    When serializing to JSON via JsonSerializer.Serialize, indentation can be controlled by setting JsonSerializerOptions.WriteIndented to true or false.

这里演示了使用JsonSerializer进行序列化并使用JsonDocument进行解析的技术。


谢谢@dbc。看起来JsonDocument.Parse对于JObject和JsonPropertyName对于其他事情对我有用。明天将转换我的应用程序并进行检查。还有一件事,我将寻找Formating.None的等效物。谢谢。 - Kamran Shahid

3

这个链接可以帮助您入门,以下是我复制的片段。

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; }
// 始终为摄氏度。 [JsonPropertyName("temp")] public int TemperatureC { get; set; }
public string Summary { get; set; }
// 不序列化此属性。 [JsonIgnore] public bool IsHot => TemperatureC >= 30; }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接