How to serialize only inherited properties of a class using a JsonConverter

后端 未结 1 626
孤独总比滥情好
孤独总比滥情好 2020-12-07 06:13

I\'m trying to serialize only the inherited properties of a class using json.net. I\'m aware of the [JsonIgnore] attribute, but I only want to do ignore them on certain occa

相关标签:
1条回答
  • 2020-12-07 07:00

    Not sure why your code doesn't work (maybe a Json.NET bug?). Instead, you can remove the properties you don't want from the JObject and write the entire thing in one call:

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Find properties of inherited class
            var classType = value.GetType();
            var classProps = classType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList();
    
            // Remove the overrided properties
            classProps.RemoveAll(t =>
            {
                var getMethod = t.GetGetMethod(false);
                return (getMethod.GetBaseDefinition() != getMethod);
            });
    
            // Get json data
            var o = (JObject)JToken.FromObject(value);
    
            // Remove all base properties
            foreach (var p in o.Properties().Where(p => !classProps.Select(t => t.Name).Contains(p.Name)).ToList())
                p.Remove();
    
            o.WriteTo(writer);
        }
    

    Alternatively, you could create your own contract resolver and filter out base properties and members:

    public class EverythingButBaseContractResolver : DefaultContractResolver
    {
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            if (member.ReflectedType != member.DeclaringType)
                return null;
            if (member is PropertyInfo)
            {
                var getMethod = ((PropertyInfo)member).GetGetMethod(false);
                if (getMethod.GetBaseDefinition() != getMethod)
                    return null;
            }
            var property = base.CreateProperty(member, memberSerialization);
            return property;
        }
    }
    

    And then use it like:

            var settings = new JsonSerializerSettings { ContractResolver = new EverythingButBaseContractResolver() };
            var json = JsonConvert.SerializeObject(rootObject, Formatting.Indented, settings);
    
    0 讨论(0)
提交回复
热议问题