Skip to content

Conversation

@RSoeborg
Copy link

@RSoeborg RSoeborg commented Sep 16, 2024

There is an issue handling nullable TypeId fields when deserializing with System.Text.Json

Consider the below:

public class Customer {
    public TypeIdDecoded Id { get; }
    // other props
    public TypeIdDecoded? DefaultShippingAddressId { get; }
}

When trying to deserialize the nullable property a JsonException is raised:

The JSON value could not be converted to System.Nullable`1[FastIDs.TypeId.TypeIdDecoded]. Path: $.defaultShippingAddressId

This PR aims to fix that.

…tory classes that can handle nullability correctly
- Added tests to handle serialization and deserialization of null properties in TypeIdDecodedContainer objects.
- Added tests for collections and dictionaries with null values.
- Updated and added tests to ensure correct serialization and deserialization of nullable TypeIdDecoded properties within arrays and plain objects.
Replaced direct converter additions in `Extensions.cs` with factory instances. Improved exception messages with more informative details in `TypeIdConverterFactory.cs` and `TypeIdDecodedConverterFactory.cs`. This enhances code maintainability and readability by leveraging factory patterns and explicit error conditions.
@firenero
Copy link
Owner

Hi @RSoeborg, sorry for a slow response. I can't reproduce the original issue based on your example. These tests pass for me:

[TestFixture]
public class NullTests
{
    private JsonSerializerOptions _options = new JsonSerializerOptions().ConfigureForTypeId();
    
    [Test]
    public void Serialized()
    {
        var item = new Customer(TypeId.Parse("type_01h455vb4pex5vsknk084sn02q").Decode(), null);
        
        var json = JsonSerializer.Serialize(item, _options);
        
        json.Should().Be("{\"Id\":\"type_01h455vb4pex5vsknk084sn02q\",\"DefaultShippingAddressId\":null}");
    }

    [Test]
    public void Deserialized()
    {
        var json = "{\"Id\":\"type_01h455vb4pex5vsknk084sn02q\",\"DefaultShippingAddressId\":null}";
        
        var item = JsonSerializer.Deserialize<Customer>(json, _options);
        
        item.Should().BeEquivalentTo(new Customer(TypeId.Parse("type_01h455vb4pex5vsknk084sn02q").Decode(), null));
    }
    
    [Test]
    public void DeserializedWithValue()
    {
        var json = "{\"Id\":\"type_01h455vb4pex5vsknk084sn02q\",\"DefaultShippingAddressId\":\"type_01h455vb4pex5vsknk084sn02q\"}";
        
        var item = JsonSerializer.Deserialize<Customer>(json, _options);

        var expected = new Customer(
            TypeId.Parse("type_01h455vb4pex5vsknk084sn02q").Decode(),
            TypeId.Parse("type_01h455vb4pex5vsknk084sn02q").Decode()
        );
        item.Should().BeEquivalentTo(expected);
    }

    public class Customer {
        public TypeIdDecoded Id { get; }
        // other props
        public TypeIdDecoded? DefaultShippingAddressId { get; }
        
        public Customer(TypeIdDecoded id, TypeIdDecoded? defaultShippingAddressId)
        {
            Id = id;
            DefaultShippingAddressId = defaultShippingAddressId;
        }
    }
}

Could you please provide a code snipped that reproduces the error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants