Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore [JsonIgnore] Attribute on Serialization / Deserialization [duplicate]

Tags:

c#

json.net

Is there a way I can ignore Json.NET's [JsonIgnore] attribute on a class that I don't have permission to modify/extend?

public sealed class CannotModify
{
    public int Keep { get; set; }

    // I want to ignore this attribute (and acknowledge the property)
    [JsonIgnore]
    public int Ignore { get; set; }
}

I need all properties in this class to be serialized/deserialized. I've tried subclassing Json.NET's DefaultContractResolver class and overriding what looks to be the relevant method:

public class JsonIgnoreAttributeIgnorerContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        // Serialize all the properties
        property.ShouldSerialize = _ => true;

        return property;
    }
}

but the attribute on the original class seems to always win:

public static void Serialize()
{
    string serialized = JsonConvert.SerializeObject(
        new CannotModify { Keep = 1, Ignore = 2 },
        new JsonSerializerSettings { ContractResolver = new JsonIgnoreAttributeIgnorerContractResolver() });

    // Actual:  {"Keep":1}
    // Desired: {"Keep":1,"Ignore":2}
}

I dug deeper, and found an interface called IAttributeProvider that can be set (it had a value of "Ignore" for the Ignore property, so that was a clue this might be something that needs changing):

...
property.ShouldSerialize = _ => true;
property.AttributeProvider = new IgnoreAllAttributesProvider();
...

public class IgnoreAllAttributesProvider : IAttributeProvider
{
    public IList<Attribute> GetAttributes(bool inherit)
    {
        throw new NotImplementedException();
    }

    public IList<Attribute> GetAttributes(Type attributeType, bool inherit)
    {
        throw new NotImplementedException();
    }
}

But the code isn't ever hit.

like image 448
Michael Avatar asked Jun 21 '16 20:06

Michael


1 Answers

You were on the right track, you only missed the property.Ignored serialization option.

Change your contract to the following

public class JsonIgnoreAttributeIgnorerContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        property.Ignored = false; // Here is the magic
        return property;
    }
}
like image 74
Orel Eraki Avatar answered Oct 20 '22 02:10

Orel Eraki