James
James

Reputation: 400

System.Text.Json add JsonIgnore attribute at runtime

I am looking a way to Serialize object using System.Text.Json but some property is ignored based on other property value.

for example:

public class Data
{
   public string Type { get; set; }
   public string A { get; set; }
   public string B { get; set; }
   public string BC { get; set; }
}

and i fill the class with this data

var data = new Data
{
   Type = "A",
   A = "data A",
   B = "data B",
   BC = "data BC"
};

when the Type value is A, i want to serialize property Type and A.

when the Type value is B, i want to serialize property Type, B, and BC.

and so on.

Is there a way to do this?

I ever made the Xml version with Custom Attribute, but when searching for System.Text.Json solution, didn't find any.

Here's my Xml version:

public static bool HasAttribute<TAttribute>(
            this PropertyInfo prop)
            where TAttribute : Attribute
{
    return prop.GetCustomAttributes(typeof(TAttribute), false).Any();
}

public static TValue GetAttributeValue<TAttribute, TValue>(
            this PropertyInfo prop,
            Func<TAttribute, TValue> valueSelector)
            where TAttribute : Attribute
{
    var att = prop.GetCustomAttributes(typeof(TAttribute), false).FirstOrDefault() as TAttribute;
    if (att != null)
    {
        return valueSelector(att);
    }
    return default(TValue);
}

private void GenerateAttributeOverrides<T>(string type, XmlAttributeOverrides attributeOverrides, PropertyInfo[] properties)
{
    foreach (var prop in properties)
    {
        var attributes = new XmlAttributes();
        if (prop.HasAttribute<ShouldSerializeAttribute>())
        {
            var acceptedTypes = prop.GetAttributeValue<ShouldSerializeAttribute, string[]>(x => x.AcceptedTypes);
            if (acceptedTypes.Contains(type))
            {
                attributes.XmlElements.Add(new XmlElementAttribute(prop.Name, prop.PropertyType);
            }
            else
            {
                attributes.XmlIgnore = true;
            }
        }
    }

thanks in advance.

Upvotes: 3

Views: 1470

Answers (1)

James
James

Reputation: 400

After looking in Custom Converters, already found my answer.

here's my converter

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

    public override void Write(Utf8JsonWriter writer, Data value, JsonSerializerOptions options)
    {
        var properties = value.GetType().GetProperties();

        writer.WriteStartObject();

        foreach (var prop in properties)
        {
            if (prop.HasAttribute<ShouldSerializeAttribute>())
            {
                var acceptedTypes = prop.GetAttributeValue<ShouldSerializeAttribute, string[]>(x => x.AcceptedTypes);
                if (acceptedTypes != null && acceptedTypes.Contains(value.Type))
                {
                    var propValue = prop.GetValue(value);
                    writer.WritePropertyName(prop.Name);
                    JsonSerializer.Serialize(writer, propValue, prop.PropertyType, options);
                }
            }
        }

        writer.WriteEndObject();
    }
}

Upvotes: 3

Related Questions