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

JsonIgnore attribute is not inherited in overridden properties #50078

Open
Tracked by #73255
jmcginty opened this issue Mar 23, 2021 · 7 comments
Open
Tracked by #73255

JsonIgnore attribute is not inherited in overridden properties #50078

jmcginty opened this issue Mar 23, 2021 · 7 comments

Comments

@jmcginty
Copy link

jmcginty commented Mar 23, 2021

Description

Marking a property in an abstract class as [JsonIgnore] does not get inherited when the property is overridden

Configuration

  • Which version of .NET is the code running on? .net Core 3.1

Other information

Example test code to show the problem

using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Xunit;

namespace Test.TallyIt.JsonLibTest
{
    internal abstract class Animal
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public DateTime Dob { get; set; }
        [JsonIgnore]
        public abstract bool IsIgnored { get; set; }
    }

    internal class Cat : Animal
    {
        public override bool IsIgnored { get; set; }
    }

    public class JsonTests
    {
        [Fact]
        public void TestSerialiseIntoCamelCase()
        {
            var cat = new Cat()
            {
                Id = 123782,
                Dob = new DateTime(2000, 7, 14),
                FirstName = "Fluffy",
                IsIgnored = true
            };

            var json = JsonSerializer.Serialize(cat);

            // This assert fails, I expected the JsonIgnore attribute to be derived
            Assert.Equal(@"{""id"":123782,""firstName"":""Fluffy"",""dob"":""2000-07-14T00:00:00""}", json);
        }
    }
}
@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Mar 23, 2021
@ghost
Copy link

ghost commented Mar 23, 2021

Tagging subscribers to this area: @eiriktsarpalis, @layomia
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Marking a property in an abstract class as [JsonIgnore] does not get inherited when the property is overridden

Configuration

  • Which version of .NET is the code running on? .net Core 3.1

Other information

Example test code to show the problem

using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Xunit;

namespace Test.TallyIt.JsonLibTest
{
    internal abstract class Animal
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public DateTime Dob { get; set; }
        [JsonIgnore]
        public abstract bool IsIgnored { get; set; }
    }

    internal class Cat : Animal
    {
        public override bool IsIgnored { get; set; }
    }

    public class JsonTests
    {
        [Fact]
        public void TestSerialiseIntoCamelCase()
        {
            var cat = new Cat()
            {
                Id = 123782,
                Dob = new DateTime(2000, 7, 14),
                FirstName = "Fluffy",
                IsIgnored = true
            };

            var json = JsonSerializer.Serialize(cat);

            // This assert fails, I expected the JsonIgnore attribute to be derived
            Assert.Equal(@"{""id"":123782,""firstName"":""Fluffy"",""dob"":""2000-07-14T00:00:00""}", json);
        }
    }
}
Author: jmcginty
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Mar 24, 2021

I can reproduce locally in .NET 5. Given that virtual properties already inherit attributes like JsonPropertyName it stands to reason that the same should be the case with JsonIgnore. @layomia thoughts?

@eiriktsarpalis eiriktsarpalis added bug and removed untriaged New issue has not been triaged by the area owner labels Mar 24, 2021
@eiriktsarpalis eiriktsarpalis added this to the Future milestone Mar 24, 2021
@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Mar 24, 2021

Triage: assigning to future since not a regression and can be worked around by applying the same attribute in the derived classes.

@Maximys
Copy link
Contributor

Maximys commented Aug 30, 2021

@layomia , I think this bug is linked with 51165. Can you get me possibility to fix they on my free time (I hope, on Saturday or Sunday of current week)?

@Jetski5822
Copy link

Just ran in to this - any idea when in 8.X this will be worked on?

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented May 28, 2024

.NET 8 has already shipped - we don't backport bugfixes to shipped versions of .NET unless they are regressions or security related bugs. In terms when this will get fixed in general, I can say with certainty that a fix is not in the cards for .NET 9.

@oddbear
Copy link

oddbear commented Jun 26, 2024

Not a solution, but it is possible to use customization as a workaround.
Something like:

void Main()
{
    var jsonSerializerOptions = new JsonSerializerOptions
    {
        TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers = { InheritJsonIgnore }
        }
    };

    var cat = new Cat()
    {
        Id = 123782,
        Dob = new DateTime(2000, 7, 14),
        FirstName = "Fluffy",
        IsIgnored = true
    };

    var json = JsonSerializer.Serialize(cat, jsonSerializerOptions);
    json.Dump(); // {"Id":123782,"FirstName":"Fluffy","Dob":"2000-07-14T00:00:00"}
}

// Modified example from: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/custom-contracts
static void InheritJsonIgnore(JsonTypeInfo jsonTypeInfo)
{
    if (jsonTypeInfo.Kind is not JsonTypeInfoKind.Object)
        return;
    
    for (int i = 0; i < jsonTypeInfo.Properties.Count; i++)
    {
        if (jsonTypeInfo.Properties[i].AttributeProvider is not PropertyInfo propertyInfo)
            continue;

        if (propertyInfo.GetCustomAttribute<JsonIgnoreAttribute>() is null)
            continue;

        jsonTypeInfo.Properties.RemoveAt(i--);
    }
}

internal abstract class Animal
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public DateTime Dob { get; set; }
    [JsonIgnore]
    public abstract bool IsIgnored { get; set; }
}

internal class Cat : Animal
{
    public override bool IsIgnored { get; set; }
}

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

No branches or pull requests

8 participants