Home >Backend Development >C++ >How to Deserialize Nested JSON into a Nested Dictionary with Type Discrimination in .NET Core?

How to Deserialize Nested JSON into a Nested Dictionary with Type Discrimination in .NET Core?

DDD
DDDOriginal
2024-12-29 08:04:13918browse

How to Deserialize Nested JSON into a Nested Dictionary with Type Discrimination in .NET Core?

Deserialization of Nested JSON into a Nested Dictionary with Type Discrimination

In .NET Core 3.1, System.Text.Json provides a standard way to deserialize JSON. By default, JSON objects are deserialized into JsonElement objects, which provide access to the JSON data structure but do not automatically convert values to their corresponding C# types.

Problem:

The goal is to deserialize nested JSON objects into Dictionary, but with the following type discrimination for JSON property values:

  • Strings as strings
  • Numbers as int/double
  • Objects as Dictionary

Solution:

To achieve this, a custom JsonConverter called ObjectAsPrimitiveConverter is necessary, as System.Text.Json does not provide out-of-the-box functionality for this specific type conversion.

The ObjectAsPrimitiveConverter provides the following capabilities:

  • Type-aware deserialization:

    • Converts strings as strings
    • Converts numbers as int/double based on a user-configurable format
    • Converts objects as Dictionary
  • Number handling:

    • Supports double or decimal precision for floating-point numbers
    • Includes an option to handle unsupported numbers as JsonElements or throw exceptions
  • Object handling:

    • Allows the user to choose between using Dictionary or ExpandoObject for objects

Implementation:

public class ObjectAsPrimitiveConverter : JsonConverter<object>
{
    // Configuration options
    FloatFormat FloatFormat { get; init; }
    UnknownNumberFormat UnknownNumberFormat { get; init; }
    ObjectFormat ObjectFormat { get; init; }

    public ObjectAsPrimitiveConverter()
        : this(FloatFormat.Double, UnknownNumberFormat.Error, ObjectFormat.Expando)
    {
    }

    public ObjectAsPrimitiveConverter(
        FloatFormat floatFormat,
        UnknownNumberFormat unknownNumberFormat,
        ObjectFormat objectFormat)
    {
        this.FloatFormat = floatFormat;
        this.UnknownNumberFormat = unknownNumberFormat;
        this.ObjectFormat = objectFormat;
    }

    // ... implementation details ...
}

public enum FloatFormat
{
    Double,
    Decimal,
}

public enum UnknownNumberFormat
{
    Error,
    JsonElement,
}

public enum ObjectFormat
{
    Expando,
    Dictionary,
}

Usage:

To deserialize JSON into a dynamic object (or ExpandoObject if configured) using the ObjectAsPrimitiveConverter, specify the converter in the JsonSerializerOptions like this:

var options = new JsonSerializerOptions
{
    Converters = { new ObjectAsPrimitiveConverter(floatFormat : FloatFormat.Double, unknownNumberFormat : UnknownNumberFormat.Error, objectFormat : ObjectFormat.Expando) },
    WriteIndented = true,
};
dynamic d = JsonSerializer.Deserialize<dynamic>(json, options);

Notes:

  • JSON allows for numbers of arbitrary precision and magnitude, while .NET primitive numeric types do not. In cases where a JSON number cannot be parsed into a .NET primitive type, the converter provides the option to return a JsonElement for the number or throw an exception.
  • The converter can be configured to use double or decimal precision for floating-point numbers and Dictionary or ExpandoObject for JSON objects.

The above is the detailed content of How to Deserialize Nested JSON into a Nested Dictionary with Type Discrimination in .NET Core?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn