Dahomey.Json icon indicating copy to clipboard operation
Dahomey.Json copied to clipboard

Duplicate Key if several type have the same discriminator

Open Itori opened this issue 2 years ago • 1 comments

If 2 types have the same discriminator, you will get a duplicate key error.

For reproduction add to DiscrinatorTests :

    public class BaseObjectResponse
    {
        public int Id { get; set; }
    }

    [JsonDiscriminator(12)]
    public class NameObjectResponse : BaseObjectResponse
    {
        public string Name { get; set; }
    }
        [Theory]
        [InlineData(DiscriminatorPolicy.Default, @"{""BaseObject"":{""$type"":12,""Name"":""foo"",""Id"":1},""NameObject"":{""Name"":""bar"",""Id"":2}}")]
        [InlineData(DiscriminatorPolicy.Auto, @"{""BaseObject"":{""$type"":12,""Name"":""foo"",""Id"":1},""NameObject"":{""Name"":""bar"",""Id"":2}}")]
        [InlineData(DiscriminatorPolicy.Never, @"{""BaseObject"":{""Name"":""foo"",""Id"":1},""NameObject"":{""Name"":""bar"",""Id"":2}}")]
        [InlineData(DiscriminatorPolicy.Always, @"{""BaseObject"":{""$type"":12,""Name"":""foo"",""Id"":1},""NameObject"":{""$type"":12,""Name"":""bar"",""Id"":2}}")]
        public void WritePolymorphicObjectDuplicateKey(DiscriminatorPolicy discriminatorPolicy, string expected)
        {
            JsonSerializerOptions options = new JsonSerializerOptions();
            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();
            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention<int>(options));
            registry.RegisterType<NameObject>();
            registry.RegisterType<NameObjectResponse>();
            registry.DiscriminatorPolicy = discriminatorPolicy;

            BaseObjectHolder obj = new BaseObjectHolder
            {
                BaseObject = new NameObject
                {
                    Id = 1,
                    Name = "foo"
                },
                NameObject = new NameObject
                {
                    Id = 2,
                    Name = "bar"
                }
            };

            string actual = JsonSerializer.Serialize(obj, options);

            Assert.Equal(expected, actual);
        }

Itori avatar Aug 27 '22 11:08 Itori

I have a similar situation, different models with different operations but a common discriminator e.g:

public class Create
{
}

[JsonDiscriminator("M")]
public class CreateProject
{
}

public class Update
{
}
[JsonDiscriminator("M")]
public class UpdateProject
{
}

attiqeurrehman avatar Nov 28 '22 12:11 attiqeurrehman