0

I'd like to serialize an object based on an interface. I've found ways to do this with contract resolvers, but the problem is it only works with properties defined as primitive types in the interface. I need to be able to serialize out non-primitive types defined in the interface.

As an example of what I want, say I have the following classes and interface.

public interface IInterface
{
    SubClass Sub { get; set; }

    int A { get; set; }
}

public class Class : IInterface
{
    public SubClass Sub { get; set; } = new();
    public int A { get; set; } = 1;
    public int B { get; set; } = 1;
}

public class SubClass
{
    public int C { get; set; } = 2;
}

If I serailize out an instance of Class, what I'd like to have serialized out is

{"Sub":{"C":2},"A":1}

How can I do this?

Edit: Someone in the comments pointed the solution in a previously asked question.

Here's the post Serialize only interface properties to JSON with Json.net

Here's the ContractResolver that worked for me.

public class InterfaceContractResolver : DefaultContractResolver
{
    private readonly Type[] _interfaceTypes;

    private readonly ConcurrentDictionary<Type, Type> _typeToSerializeMap;

    public InterfaceContractResolver(params Type[] interfaceTypes)
    {
        _interfaceTypes = interfaceTypes;

        _typeToSerializeMap = new ConcurrentDictionary<Type, Type>();
    }

    protected override IList<JsonProperty> CreateProperties(
        Type type,
        MemberSerialization memberSerialization)
    {
        var typeToSerialize = _typeToSerializeMap.GetOrAdd(
            type,
            t => _interfaceTypes.FirstOrDefault(
                it => it.IsAssignableFrom(t)) ?? t);

        var props = base.CreateProperties(typeToSerialize, memberSerialization);

        // mark all props as not ignored
        foreach (var prop in props)
        {
            prop.Ignored = false;
        }

        return props;
    }
}
Vic
  • 55
  • 7
  • Unfortunately, without writing custom serialization converters, you can't. Json.net uses reflection on the actual objects being passed to it, and interfaces are not considered. – Lasse V. Karlsen Sep 11 '21 at 21:14
  • 1
    You can do it with a custom contract resolver. See [Serialize only interface properties to JSON with Json.net](https://stackoverflow.com/q/17123821/3744182), which looks to be a duplicate. Agree? – dbc Sep 12 '21 at 06:00
  • I previously tried a few of the answers there with no luck. But I went down further in the answers and tried another one which word as I needed. Thanks. – Vic Sep 12 '21 at 15:54

0 Answers0