3

I need help in converting following code which is using newtonsoft to System.Text.Json

string myList = null!;
string jSon = /* From some source */;
object jsonObject = JsonConvert.DeserializeObject(jSon, typeof(object));

// Loop through the keys
foreach (var jsonList in ((Newtonsoft.Json.Linq.JObject)(jsonObject)))
{                   
    if (jsonList.Key == "myKey")
    {                       
        foreach (object o in (jsonList.Value.ToArray()))
        {                           
            myList += o.ToString().ToUpper() + ',';
        }
    }
}

json like:

{"myKey":["fir","dsdsd"],"status":"ok"}
0

1 Answer 1

3

With System.Text.Json, you can parse arbitrary JSON using either the JsonDocument or JsonNode document object models. The differences are:

  • JsonNode is modifiable and is, in my opinion, easier to work with as it most closely resembles Newtonsoft's LINQ to JSON model. It was added in .NET 6.
  • JsonDocument is read-only, but may be a little more memory-efficient in parsing huge JSON files. It was introduced as part of the original System.Text.Json API in .NET Core 3.0.

Thus, using JsonNode, your code can be rewritten as follows:

static string? QueryJson(string json, string myKey, bool addComma = false)
{
    // Parse to a JsonNode and cast to JsonObject.  An exception is thrown if not an object
    var node = JsonNode.Parse(json)!.AsObject(); 
    
    // Query the array of strings
    var query = (node[myKey] as JsonArray)?.Select(i => i?.ToString().ToUpper());
    if (query == null)
        return null; // Return null if key not found as per original code
    if (addComma)
        query = query.Concat(new [] { "" });

    // Join the string array into a single comma-separated string
    return string.Join(',', query);
}

And here is a version of the same logic using JsonDocument:

static string? QueryJsonWithJsonDocument(string json, string myKey, bool addComma = false)
{
    // Parse to a JsonNode and cast to JsonObject.  An exception is thrown if not an object
    using var doc = JsonDocument.Parse(json);

    // Query the array of strings
    var query = doc.RootElement.Get(myKey)?.EnumerateArray().Select(e => e.GetString()?.ToUpper());
    if (query == null)
        return null; // Return null if key not found as per original code
    if (addComma)
        query = query.Concat(new [] { "" });

    // Join the string array into a single comma-separated string
    return string.Join(',', query);
}

This uses the following extension method from here to check for missing or null properties:

public static partial class JsonExtensions
{
    public static JsonElement? Get(this JsonElement element, string name) => 
        element.ValueKind != JsonValueKind.Null && element.ValueKind != JsonValueKind.Undefined && element.TryGetProperty(name, out var value) 
            ? value : (JsonElement?)null;
}

Notes:

  • You tagged your question . This version goes out of support in about a month, on December 13, 2022. If you are using this version you will need to use JsonDocument since JsonNode was introduced in .NET 6.

  • JsonDocument is disposable, and should be disposed to ensure that pooled memory is returned to the system. JsonNode is not disposable.

  • It will be more efficient to use string.Join() than manually building a comma-separated string using multiple string additions.

  • Your current code adds a trailing comma to the string: FIR,DSDSD,. This looks like a bug, but if you want that you can make string.Join() add a trailing comma by adding an extra empty string to the query.

Demo fiddle here.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks @dbc. i know 3.1 is expiring but there are places where even 2.1/2.2 is used in production. luckily my this logic is in .net 6 solution so i will use the JsonNode solution. about the trailing comma i have a legacy code where first they create string like initial solution then removed it via extension method :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.