Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Text.Json exception when trying to serialize NaN - problem with NTSTopologySuite #40140

Closed
fededim opened this issue Jul 30, 2020 · 1 comment

Comments

@fededim
Copy link

fededim commented Jul 30, 2020

I am working on a project based asp.net core 3.1, EF Code First and NTSTopologySuite. I do have Point properties in my entites to specify geographic location, however when I try to return the entity from a standard WebApi2 controller the serialization fails with the following error:

System.ArgumentException: .NET number values such as positive and negative infinity cannot be written as valid JSON.
at System.Text.Json.ThrowHelper.ThrowArgumentException_ValueNotSupported()
at System.Text.Json.Utf8JsonWriter.WriteNumberValue(Double value)
at System.Text.Json.Serialization.Converters.JsonConverterDouble.Write(Utf8JsonWriter writer, Double value, JsonSerializerOptions options)
at System.Text.Json.JsonPropertyInfoNotNullable`4.OnWrite(WriteStackFrame& current, Utf8JsonWriter writer)
at System.Text.Json.JsonPropertyInfo.Write(WriteStack& state, Utf8JsonWriter writer)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

The problem is that the Point class has some properties with NaN values. I could skip the serialization of Point properties with JsonIgnore attribute, but that's not what I need (I need to have the geographic location). Any plan to support NaN values in JSON serialization of Double ? As a matter of fact, double datatype has also this possible value and I do not see why it can't be serialized.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Jul 30, 2020
@layomia
Copy link
Contributor

layomia commented Jul 30, 2020

NaN and other floating point constants (infinity, negative infinity) are not valid for (de)serialization using System.Text.Json In ASP.NET 3.1, hence the error you are seeing.

For .NET 5.0, we've added a "number handling" feature that allows you to opt in to read and write these floating point constants - #39363. This feature will be available in .NET preview 8, but will not be ported to 3.1

The work around for 3.1 is to add a custom converter for the double type to a JsonSerializerOptions instance, or on each property that requires this handling.

public class DoubleConverter : JsonConverter<double>
{
    public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String && reader.GetString() == "NaN")
        {
            return double.NaN;
        }

        return reader.GetDouble(); // JsonException thrown if reader.TokenType != JsonTokenType.Number
    }

    public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
    {
        if (double.IsNaN(value))
        {
            writer.WriteStringValue("NaN");    
        }
        else
        {
            writer.WriteNumberValue(value);
        }
    }
}

@layomia layomia closed this as completed Jul 30, 2020
@layomia layomia removed the untriaged New issue has not been triaged by the area owner label Jul 30, 2020
@layomia layomia added this to the 5.0.0 milestone Jul 30, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants