0

I want to write a JsonConverter it can convert a determinate property type but only depending on the class they are defined.

I am registering the JsonConverter globally via Web API:

var config = GlobalConfiguration.Configuration;
var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.Converters.Add(new SomeConverter());

The Converter can convert for example objects of type MyType.

public override bool CanConvert(Type objectType)
{
    return typeof(MyType).IsAssignableFrom(objectType);
}

But now I want to control want the converter should be used or not.

I thought something like that:

[IgnoreSomeConverter]
public class ClassA
{
    public MyType PropMyType {get;set;}
}

public class ClassB
{
    public MyType PropMyType {get;set;}
}

So I would like that the SomeConverter serialized and deserialized the properties MyType only when the property is defined in a class not decorated with the CustomAttribute IgnoreSomeConverter. In the example I want to use the converter for ClassB but not for ClassA. Any idea to get that?

user9923760
  • 596
  • 2
  • 8
  • 18
  • You can do it by applying `NoConverter` from the [linked answer](https://stackoverflow.com/a/39739105/3744182) to the properties that should not use the global converter, i.e. `public class ClassA { [JsonConverter(typeof(NoConverter))] public MyType PropMyType {get;set;} }` – dbc Sep 27 '18 at 22:25
  • And is it possible to do that by defining the NoConverter in the level class instead in the level property? – user9923760 Sep 27 '18 at 22:50
  • Not out of the box. That would require a custom contract resolver. Is that a requirement to answer the question? The linked answer seems simple enough, and either way you will need to add serialization-specific attributes to your types. But if it is a requirement, the question can get re-opened. – dbc Sep 27 '18 at 22:54
  • Yes , it is a requirement. I defined in a `DefaultContractResolver` : `property.Converter = new NoConverter();` if the class has the attribute IgnoreSomeConverter. To acces the class: `Type myType = Type.GetType(member.ReflectedType.AssemblyQualifiedName);` – user9923760 Sep 27 '18 at 23:12
  • Yes, that's a correct way to go. Do you want me to re-open the question so you can answer it yourself? – dbc Sep 27 '18 at 23:13
  • OK, I reopened it so you can go ahead and answer it yourself. – dbc Sep 27 '18 at 23:21

1 Answers1

0

Newtonsoft.JSON package contains DefaultContractResolver class, register it on your serializer settings, create a derived class from it, this you can adopt to class or a class property.

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

        property.ShouldSerialize = i => false;
        property.Ignored = true;

        return property;
    }
}

And register it.

    var serializer = new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver() };

Function has MemberInfo argument from which you can attributes, etc.

narekye
  • 114
  • 3
  • In the question, OP does want to serialize `ClassA.PropMyType`, just without using the global converter. This answer prevents `ClassA.PropMyType` from being serialized at all which is not what is wanted. – dbc Sep 27 '18 at 22:28