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) useDictionary<string, object>
(orExpandoObject
, which implementsDictionary<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 isobject
. 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>
orobject []
. A typedList<T>
orT []
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.