TheDoomDestroyer
TheDoomDestroyer

Reputation: 3085

How to ignore property during deserialization using JsonSerializerSettings

Is there a way to dynamically exclude a property from JSON during the deserialization? An example JSON:

{"time":1516176813,"signature":"IS1cJRqj1FVyTWWDhFpFVw==","data":"ab9984617a6ec835844bacbd47bfb59c"}

Here, I'd like to exclude the "si" property and I have extended the DefaultContractResolver:

public class IgnorePropertiesResolver : DefaultContractResolver
{
    private readonly HashSet<string> _ignoreProps;

    public IgnorePropertiesResolver(IEnumerable<string> propNamesToIgnore)
    {
        _ignoreProps = new HashSet<string>(propNamesToIgnore);
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        if (_ignoreProps.Contains(property.PropertyName))
        {
            property.ShouldSerialize = _ => false;
            property.ShouldDeserialize = _ => false;
        }
        return property;
    }
}

However, when I call the DeserializeObject method, the property is still present.

var ignoredProperties = new List<string> { "si" };
JsonConvert.DeserializeObject<T>(source, new JsonSerializerSettings
{
    ContractResolver = new IgnorePropertiesResolver(ignoredProperties)
});

I know I can use JObject.Property(propertyName).Remove(), but I'd like to avoid that.

Upvotes: 1

Views: 2212

Answers (1)

J.Loscos
J.Loscos

Reputation: 2917

Instead of a ContractResolver you can use a custom JsonConverter :

  public class IgnorePropertyConverter<T> : JsonConverter 
        where T : new()
    {
        private readonly HashSet<string> _ignoreProps;

        public IgnorePropertyConverter(IEnumerable<string> propNamesToIgnore)
        {
            _ignoreProps = new HashSet<string>(propNamesToIgnore);
        }
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jobject = JObject.Load(reader);

            var model = new T();

            foreach (var prop in _ignoreProps)
                jobject.Remove(prop);

            serializer.Populate(jobject.CreateReader(), model);

            return model;
        }

        public override bool CanWrite
        {
            get { return false; }
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    class MyModel
    {
        public int Time { get; set; }
        public string Data { get; set; }
    }

        var myModel = JsonConvert.DeserializeObject<MyModel>(json, new IgnorePropertyConverter<MyModel>(new List<string> { "signature" }));

Upvotes: 1

Related Questions