How can I ignore properties of a subclass I dont own during serialization?

jsontypeinfo
jsonignoreproperties
jackson exclude from serialization
jackson polymorphic deserialization without annotations
jackson default typing
enabledefaulttyping
jsonignore conditional
how to not serialize a property in java

I have a class Tempo. I can alter freely:

public class Tempo
{
    public Period Period { get; set; }
    public int Value { get; set; } // in fact int should be a T here if it matters.

    // more properties here
}

Period is a class from an external dependency I cannot alter.

public class Period
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public int Count { get; set; }
    public string Foo { get; set; }

    // more properties here
}

Period is a huge class with a lot of properties that I dont want to serialize. So no sweet [JsonIgnore] for me. From Period I would like to keep only the properties Start and End.

I tried to use a DefaultContractResolver without success:

class TempoResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var props = base.CreateProperties(type, memberSerialization);
        return props
            .Where(p => p.PropertyName != "Period") // how to filter subclass?
            .ToList();
    }
}

I tried to use a JsonConverterwithout success:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    var jo = new JObject();
    var type = value.GetType();
    jo.Add("type", type.Name);
    foreach (var prop in type.GetProperties().Where(x => x.CanRead))
    {
        object propVal = prop.GetValue(value, null);
        if (propVal != null)
        {
            jo.Add(prop.Name,
             JToken.FromObject(propVal, serializer));  // how to filter subclass?
        }
    }
    jo.WriteTo(writer);
}

In both case, I am not sure how to filter Period. How can I ignore properties of a subclass I dont own during serialization?

Try it Online!

Note:

  • I use C#6
  • I use JSON.NET

Make the subclass:

public class Periodic
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

Use the custom converter with this code:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    Periodic periodic = (Periodic)value;
    JToken t = JToken.FromObject(periodic);
    t.WriteTo(writer);
}

Exclude Fields from Serialization in Gson, Explore the options available to exclude fields from serialization in Gson. for excluding one or more fields of a Java class and its subclasses from Gson serialization. Gson serializer will ignore every field declared as transient: If we have a class with a hundred of fields, and we only want to exclude one� During the serialization process all the public and private fields of a class are serialized by default. Fields marked with NonSerializedAttribute are excluded during serialization. If you are using the XmlSerializer class to serialize an object, use the XmlIgnoreAttribute class to get the same functionality.

You can create strongly typed JsonConverter for Period class:

public class PeriodConverter : JsonConverter<Period>
{
    public override void WriteJson(JsonWriter writer, Period period, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        writer.WritePropertyName(nameof(Period.Start));
        writer.WriteValue(period.Start);
        writer.WritePropertyName(nameof(Period.End));
        writer.WriteValue(period.End);
        writer.WriteEndObject();
    }

    public override Period ReadJson(JsonReader reader, Type objectType, Period existingValue, bool hasExistingValue,
        JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }
}

Usage:

var tempo = new Tempo
{
    Period = new Period
    {
        Start = DateTime.Now.AddDays(-1),
        End = DateTime.Now.AddHours(-1),
        Count = 42,
        Foo = "Foo"
    },
    Value = 42
};

var result = JsonConvert.SerializeObject(tempo, new PeriodConverter());
var regularJson = JsonConvert.SerializeObject(tempo);

regularJson will have all properties from Period:

{"Period":{"Start":"2019-04-08T12:21:39.1525361+03:00","End":"2019-04-09T11:21:39.1535328+03:00","Count":42,"Foo":"Foo"},"Value":42}

and result only expected:

{"Period":{"Start":"2019-04-08T12:21:39.1525361+03:00","End":"2019-04-09T11:21:39.1535328+03:00"},"Value":42}

Update

Code in WriteJson can be simplified with anonymous object:

public override void WriteJson(JsonWriter writer, Period period, JsonSerializer serializer)
{
    var token = JToken.FromObject(new {Start = period.Start, End = period.End});
    token.WriteTo(writer);
}

Inheritance in Jackson, Ignoring Properties from a Supertype Sometimes, some properties inherited from superclasses need to be ignored during serialization or deserialization. This can be achieved by one of three methods: annotations, mix-ins and annotation introspection. Recommend:c# - RestSharp - how to influence JSON serialization (naming) using SerializeAs attribute as expected 4 answers I am trying to talk to a REST service and I'm trying to call a POST method where I need to provide some data in the post body.

A solution would be to use a subset of Period:

// your external dependency
public class Period
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public int Count { get; set; }
    public string Foo { get; set; }
}

// your copycat with only the properties you really need
public class Periodic
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

public class Tempo
{
    public Periodic Period { get; set; }
    public int Value { get; set; }
}

public static void Main()
{
    var period = new Period{Count = 1, Foo = "bar", Start = DateTime.Now, End = DateTime.Now.AddDays(1)};
    var tempo = new Tempo{Value = 1, Period = new Periodic {Start = period.Start, End = period.End} };

    Console.WriteLine(JsonConvert.SerializeObject(tempo));
}

Try it online!

You can also use a library like Automapper to handle the mapping between the external class and the copycat. For two properties, it can be a bit overkill though.

Advanced Newtonsoft.Json: Dynamically rename or ignore , I use this resolver in my project NSwag, a Swagger/Open API or rename properties - for example you want to serialize a property in a Let's have a look at the standard way to ignore or rename a property with Newtonsoft. The attribute on a property causes the property to be omitted from the JSON during serialization. The IgnoreNullValues global option lets you exclude all null-value properties. The IgnoreReadOnlyProperties global option lets you exclude all read-only properties. These options don't let you:

Conditional Property Serialization, NET has the ability to conditionally serialize properties by placing a don't serialize the Manager property if an employee is their own manager return ( Manager� Troy -- simply flag your property with the XmlIgnoreAttribute. When you use an instance of this property's parent class within the context of a web service the XML serializer will automatically ignore it. AJAX intercepts the outgoing XML SOAP message and rewrites it as JSON.

Object Serialization with Inheritance in Java, Serialization is a mechanism of converting the state of an object into a byte Case 1: If superclass is serializable then subclass is automatically If the superclass is serializable but we don't want the subclass to be By overriding these methods, we are just implementing our own custom serialization. Individually, nullable and optional properties can be handled trivially by Kotlin’s own serialization library, kotlinx.serialization. However, handling both cases simultaneously takes a little

Jackson Annotations for JSON (Part 2): Serialization, Jackson provides several annotations that you can use in POJOs to serialize annotation can be used when you don't want to declare a property or a the object would have been serialized in the order found in the class. You can also customize the XML stream by deriving from an existing class and instructing the XmlSerializer instance how to serialize the new class. For example, given a Book class, you can derive from it and create an ExpandedBook class that has a few more properties.

Comments
  • In your JsonConverter, you could substitute Period with a simplified class (or an anonymous object) and serialize that instead.
  • @John & 500 - Internal Server Error, a subset is my current solution. I am not sure it is the best way to handle it.
  • you could create a dto, fill the properties you need or use automapper and serialize that
  • @Arrangemonk Exactly my thought! I just added it to my answer :)
  • If you are using a subclass, why do you need a custom converter? How does it compare to my answer?
  • The difference is the fact that you can mantain the original object this way
  • Ok, I get it. The idea is to keep Period in Tempo, so another dev using Tempo can benefit from the complete Period if he is using the object directly. Beside I expose only Periodic to the JSON API. I see the difference now.
  • Yes exactly, hope my answer helped
  • In the end, I might switch from my answer to yours. :)
  • doesnt work in .netfiddle. I will try in local.
  • Worked as expected in local. I think using a dto is easier to read/use/maintain, but thank you for showing how to solve this problim with a JsonConverter.
  • That would be my first choice as well. If you can put inheritance to use, do it.