azure-sdk-for-net icon indicating copy to clipboard operation
azure-sdk-for-net copied to clipboard

[BUG] Deserializing `null` BoundingBox throws an exception

Open goncalo-oliveira opened this issue 7 months ago • 2 comments

Library name and version

Azure.Core 1.40.0

Describe the bug

Consider the following GeoJson point

    {
        "coordinates": [
            -1.740572,
            52.487343
        ],
        "type": "Point",
        "crs": null,
        "bbox": null
    }

Deserializing this into a GeoObject should result in a successful operation and a valid object. The BoundingBox property is after all, nullable.

public abstract class GeoObject
{
    // ...

    public GeoBoundingBox? BoundingBox { get; }

    // ...
}

The code used to deserialize the JSON string

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};

var point = JsonSerializer.Deserialize<GeoObject>( json, options );

Looking at the source code, the deserializer allows a null value if the property doesn't exist, but if the property exists, it expects it to be an array.

Expected behavior

The expected result would be a successful result and a valid instance of a GeoObject with BoundingBox set as null.

Actual behavior

The actual result is an exception being through because the deserializer is expecting an array.

tem.Text.Json.JsonException : The JSON value could not be converted to Azure.Core.GeoJson.GeoObject. Path: $ | LineNumber: 8 | BytePositionInLine: 1.
---- System.InvalidOperationException : The requested operation requires an element of type 'Array', but the target element has type 'Null'.
   at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, Utf8JsonReader& reader, Exception ex)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
   at ...

Reproduction Steps

As described before, using the following json

    {
        "coordinates": [
            -1.740572,
            52.487343
        ],
        "type": "Point",
        "crs": null,
        "bbox": null
    }

And the code snippet to deserialize it.

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};

var point = JsonSerializer.Deserialize<GeoObject>( json, options );

Environment

.NET SDK:
 Version:           8.0.100
 Commit:            57efcf1350
 Workload version:  8.0.100-manifests.6c33ef20

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  14.5
 OS Platform: Darwin
 RID:         osx-arm64
 Base Path:   /usr/local/share/dotnet/sdk/8.0.100/

.NET workloads installed:
 Workload version: 8.0.100-manifests.6c33ef20
There are no installed workloads to display.

Host:
  Version:      8.0.0
  Architecture: arm64
  Commit:       5535e31a71

.NET SDKs installed:
  6.0.420 [/usr/local/share/dotnet/sdk]
  7.0.400 [/usr/local/share/dotnet/sdk]
  8.0.100 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.28 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.10 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.28 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.10 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  x64   [/usr/local/share/dotnet/x64]
    registered at [/etc/dotnet/install_location_x64]

Environment variables:
  Not set

goncalo-oliveira avatar Jul 01 '24 13:07 goncalo-oliveira