0

Is there a way to specify which properties to include or exclude when Serializing a class using System.Text.Json.Serialization?

I know that there is the member attribute which I can use (JsonIgnoreAttribute, JsonIgnoreCondition). But I need a way to include some properties in some scenario and exclude other properties in another scenario.

For example:

  • in scenario 'A' I need to include property foo.name
  • in scenario 'B' I need to exclude property foo.name

JsonIgnoreAttribute will always exclude a property. JsonIgnoreCondition is base on Property value.

In the Newtonsoft JSON library there is the ContractResolver that do this job. but I really wish to not use 2 JSon serialization engine in my project.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Hugo
  • 2,077
  • 2
  • 28
  • 34
  • You can specify a condition on `JsonIgnore` via `JsonIgnoreCondition`. Ignore when the value is the `default` or `null`. Are you looking for these or your scenarios are more "dynamic"? If so, could you please elaborate on that part? – Peter Csala Oct 14 '21 at 14:39
  • JsonIgnoreCondition is base the property value. I need a way to include or exclude properties base on the context. – Hugo Oct 14 '21 at 14:50
  • 2
    In that case I think you have several options. 1) You can write multiple custom `JsonConverter`s and call the appropriate one when the condition is met. 2) Create a generic one, which accepts a list of property selector expressions. And serialize only those which are passed through the ctor. – Peter Csala Oct 14 '21 at 14:56
  • 1
    3) Use a [JsonDocument to iterate through the properties](https://stackoverflow.com/a/58566925/13268855) and do the branching inside the converter. It is only viable if you can pass the context to the converter. – Peter Csala Oct 14 '21 at 14:59
  • 1
    That look great, I'll try it! – Hugo Oct 14 '21 at 15:17

1 Answers1

1

For the record

As Peter Csala suggested, I ended up using JsonConverter It work perfectly with what I need.

The concept is:

public class BaseTypeOnlyConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();

        var t = value.GetType();

        var propertiesName = t.GetProperties()
            .Where(o => ShouldInclude(o))
            .Select(o => o.Name.ToLower())
            .ToList();

        using (var document = JsonDocument.Parse(JsonSerializer.Serialize(value)))
        {
            foreach (var property in document.RootElement.EnumerateObject())
            {
                if (propertiesName.Contains(property.Name.ToLower()))
                    property.WriteTo(writer);
            }
        }

        writer.WriteEndObject();
    }

    private bool ShouldInclude(PropertyInfo propertyInfo)
    {
          //Do checkup ...
    }
}
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Hugo
  • 2,077
  • 2
  • 28
  • 34
  • I like also to share this link that was use has example: https://www.thinktecture.com/en/asp-net/aspnet-core-3-0-custom-jsonconverter-for-the-new-system_text_json/ – Hugo Oct 14 '21 at 15:54
  • Also here I related article that I didn't find before posting: https://stackoverflow.com/questions/58566735/how-to-exclude-a-property-from-being-serialized-in-system-text-json-jsonserializ?noredirect=1&lq=1 – Hugo Oct 14 '21 at 17:12
  • You can edit your own post to extend it with further information. BTW the SO link in your 2nd comment is the same as I've shared with you in my 3rd comment on your question. :D – Peter Csala Oct 15 '21 at 06:25