C# JsonDocument.Parse() Auto casting

71 Views Asked by At

I'm coding using C#.

When GET request, I get json format string like { "code": 2312, "price": 98.322, ... }

to parse, I use System.Text.Json.JsonDocument.Parse(jsonString) function.

I think they're type-casting internally. But because of the floating-point error, I want JsonDocument.Parser to parse the string as it is.

You can also create a class and use JsonSerializer.Deserialize, but it is cumbersome because there are too many json properties.

2

There are 2 best solutions below

0
Lito Bezos On

I struggled a little to understand your error here, but from what i gathered it seems you want to process the numbers as strings, this can be done by adding options to your json serialiser:

var options = new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true,
            NumberHandling = JsonNumberHandling.AllowReadingFromString // Handle floating-point numbers as strings
        };

        // Deserialize JSON to object
        var jsonObject = JsonSerializer.Deserialize<JsonElement>(jsonString, options);
0
Mushroomator On

You can configure this behavior using JsonSerializerOptions.NumberHandling property which has the following values:

Enum value Value Description
AllowNamedFloatingPointLiterals 4 The "NaN", "Infinity", and "-Infinity" String tokens can be read as floating-point constants, and the Single and Double values for these constants will be written as their corresponding JSON string representations.
AllowReadingFromString 1 Numbers can be read from String tokens. Does not prevent numbers from being read from Number token.
Strict 0 Numbers will only be read from Number tokens and will only be written as JSON numbers (without quotes).
WriteAsString 2 Numbers will be written as JSON strings (with quotes), not as JSON numbers.

You will wan to use NumberHandling = JsonNumberHandling.Strict. The default value for ASP.NET Core is JsonNumberHandling.AllowReadingFromString. From .NET 9 onwards you will be able to access the defaults this using the JsonSerializerOptions.Web singleton (See MS Docs - Web defaults for JsonSerializerOptions).

You can configure this as a parameter to JsonSerailizer.Deserialize()).

var jsonString = """
    { 
        "code": "2312", 
        "price": "98.322"
    }
    """;

var result = JsonSerializer.Deserialize<MyObject>(jsonString, new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
    NumberHandling = JsonNumberHandling.Strict
})!;
Console.WriteLine($"Code: {result.Code}, Price: {result.Price}");


class MyObject {
    public string Code { get; set; }
    public string Price { get; set;}
}

If you were to change the properties to types int and float/ double you would get a JsonException when parsing.

Or, you can also configure this globally using AddJsonOptions() for all your controllers in ASP.NET Core:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
    .AddJsonOptions(x => x.JsonSerializerOptions.NumberHandling = JsonNumberHandling.Strict); 

However, once you make you object properties strings which you will have to do, you can omit to specify the NumberHandling since it then a conversion is no longer necessary.