2

I've made a class from the Attribute type

   public class DemoAttribute : Attribute {
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    public string Label { get; private set; }

    public DemoAttribute(string label = null) {
        this.Label = label;
    }
}

When I try to serialize it with System.Text.Json

 var demo = new DemoAttribute("test");
 var json = JsonSerializer.Serialize(demo);

I get an InvalidOperationException:

Method may only be called on a Type for which Type.IsGenericParameter is true.

Can I serialize an Attribute without first copying it's properties to a 'regular' class with the same propeties?

Edit/Addition I'm using a far more extensive attribute with metadata on a property like (on the front end) what's the label, help-text, icon, validation rules, placeholder, etc. With reflection I get the attribute for the properties and I want to serialize it (the properties of the attribute) so I can send it to the front end.

dbc
  • 104,963
  • 20
  • 228
  • 340
Robert H
  • 23
  • 1
  • 4
  • 3
    If you could serialize the attribute, what would you then do with it? [This](https://stackoverflow.com/a/24413055/11683)? – GSerg Oct 15 '21 at 10:24
  • My guess is there's something on `Attribute` that it doesn't like. What that is, I don't know. – ProgrammingLlama Oct 15 '21 at 10:24
  • 2
    @Llama Most likely same underlying reason as in https://stackoverflow.com/a/36924994/11683. – GSerg Oct 15 '21 at 10:25
  • Felt JSON should be mentioned either in the tags or the title since the (No restriction on what type of serialization) answer to the question as posed is Yes, since they're serialized into assemblies during the compilation process. – Damien_The_Unbeliever Oct 15 '21 at 10:32
  • This is .Net framewoark so Core is likely different, but you can see there is a LOT going on inside that Attribute class https://referencesource.microsoft.com/#mscorlib/system/attribute.cs. Ignoring the label is the least of your problems – Liam Oct 15 '21 at 10:36
  • 1
    @Liam: On the other hand, the reference source also shows that `Attribute` has no internal state (almost all the stuff in the cs file is static) and that it is marked as `[Serializable]`. So, theoretically, it should work. – Heinzi Oct 15 '21 at 10:38
  • 1
    What is the *full* exception text? – Panagiotis Kanavos Oct 15 '21 at 10:39
  • 2
    Can you explain how you use this? Given a class with a property with a `[DemoAttribute("test")]`, how will you serialize this? – CodeCaster Oct 15 '21 at 10:40
  • @PanagiotisKanavos The exception: Method may only be called on a Type for which Type.IsGenericParameter is true. at System.RuntimeType.get_DeclaringMethod() at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) ... – Robert H Oct 15 '21 at 11:19
  • @GSerg I added some info to the question – Robert H Oct 15 '21 at 11:28

1 Answers1

0

Attribute has TypeId property which by default contains type of the attribute (see the remarks in docs), which fails during serialization when using System.Text.Json. You can override this property and ignore it:

public class DemoAttribute : Attribute
{
    [JsonIgnore]
    public override object TypeId { get; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    public string Label { get; private set; }

    public DemoAttribute(string label = null)
    {
        this.Label = label;
    }
}
Guru Stron
  • 102,774
  • 10
  • 95
  • 132