Home > Software engineering >  Create JSON object using System.Text.Json
Create JSON object using System.Text.Json

Time:06-17

I am working on migrating from Json.Net to System.Text.Json. I am not sure how we can build json object like below code using System.Text.Json. I tried lots of workaround but nothing seems working. I know we can do this using JsonObject from Dot net 6 , but I am using Dot net core 5.

Newtonsoft code:

var json = new JObject(
    new JProperty("Status", result.Status.ToString()),
    new JProperty("Duration", result.TotalDuration.TotalSeconds.ToString()));
if (result.Entries.Any())
{
    var entries = new JObject(result.Entries
        .Select(d => new JProperty(d.Key, new JObject(new JProperty("Status", d.Value.Status.ToString()), new JProperty("Duration", d.Value.Duration.TotalSeconds.ToString()), new JProperty("Description", d.Value.Description)))));

    json.Add(new JProperty("result", entries));
}

CodePudding user response:

In .NET 5 you can use a combination of dictionaries and anonymous types to construct free-form JSON on the fly. For instance, your sample code can be rewritten for System.Text.Json as follows:

var json = new Dictionary<string, object>
{
    ["Status"] = result.Status.ToString(),
    ["Duration"] = result.TotalDuration.TotalSeconds.ToString(NumberFormatInfo.InvariantInfo),
};

var entries = result.Entries.ToDictionary(
    d => d.Key,
    d => new { Status = d.Value.Status.ToString(), Duration = d.Value.Duration.TotalSeconds.ToString(NumberFormatInfo.InvariantInfo), Description = d.Value.Description } );
if (entries.Count > 0)
    json.Add("result", entries);

var newJson = JsonSerializer.Serialize(json, new JsonSerializerOptions { WriteIndented = true });

Notes:

  • When constructing a JSON object with properties whose values have mixed types (like the root json object in your example) use Dictionary<string, object> (or ExpandoObject, which implements Dictionary<string, object>).

    You must use object for the value type because System.Text.Json does not support polymorphism by default unless the declared type of the polymorphic value is object. For confirmation, see How to serialize properties of derived classes with System.Text.Json:

    You can get polymorphic serialization for lower-level objects if you define them as type object.

  • When constructing a JSON object with a fixed, known set of properties, use an anonymous type object.

  • When constructing a JSON object with runtime property names but fixed value types, use a typed dictionary. Oftentimes LINQ's ToDictionary() method will fit perfectly, as is shown above.

  • Similarly, when constructing a JSON array with values that have mixed types, use List<object> or object []. A typed List<T> or T [] may be used when all values have the same type.

  • When manually formatting numbers or dates as strings, be sure to do so in the invariant locale to prevent locale-specific differences in your JSON.

Demo fiddle here.

  • Related