Skip to content

Serializing base class with discriminator property results in KeyNotFoundException #79

@CK-Yong

Description

@CK-Yong

Hello, awesome package you have here. However, I have found a potential bug when you are serializing a base type while enabling discriminators. I have added a failing test below.

    public class Test
    {
        [Fact]
        public void BreakingTest()
        {
            var input = new[] {new Cat(), new Animal()};

            var serializersettings = new JsonSerializerSettings();
            serializersettings.Converters.Add(
                JsonSubtypesConverterBuilder
                    .Of(typeof(Animal), "Type")
                    .SerializeDiscriminatorProperty()
                    .RegisterSubtype(typeof(Cat), typeof(Cat).Name)
                    .Build());

            var result = String.Empty;
            var exception = Record.Exception(() => result = JsonConvert.SerializeObject(input, serializersettings));
            
            Assert.Null(exception);
            Assert.Equal("[{\"Type\":\"Cat\"},{\"Type\":\"Animal\"}]", result);
        }
    }

public class Cat : Animal{}

public class Animal{}

Expected behavior

When you serialize a base type with discriminators enabled, it'll be serialized with the base type as the discriminator value. See also provided test case.

Actual behavior

I get the following error:

System.Collections.Generic.KeyNotFoundException: The given key '(...).Animal' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at JsonSubTypes.JsonSubtypesConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty) in /_/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs:line 652
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) in /_/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs:line 691
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) in /_/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs:line 80
(...)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions