json.netjsonschemapostsharp

Properties Added with Aspects Not in Generated JSON Schema


I'm trying to generate JSON Schemas using Newtonsoft JSON Schema. Regular properties added in my POCO class are added to the schema when it is generated. I'm also using PostSharp Aspects to add properties, but none of those are added to the schema.

This is a Console application targeting .NET 4.7.2.

Here is my Console application:

public class Program
{
    private static void Main(string[] args)
    {
        JSchemaGenerator gen = new JSchemaGenerator();
        JSchema schema = gen.Generate(typeof(MyClass));
        File.WriteAllText("C:\\Temp\\TestSchema.json", schema.ToString());
    }
}

Here is my aspect:

[PSerializable]
public class TestAspect : InstanceLevelAspect
{
    [IntroduceMember]
    [JsonProperty(Required = Required.Always)]
    public string AspectProp { get; set; }
}

And here is my POCO:

[TestAspect]
public class MyClass
{
    public int MyProperty { get; set; }
}

Finally, here is the generated schema:

{
  "type": "object",
  "properties": {
    "MyProperty": {
      "type": "integer"
    }
  },
  "required": [
    "MyProperty"
  ]
}

The MyProperty property is in the schema, but AspectProp - the property added by the aspect - is not.

When I open the exe in a decompiler, I can see that AspectProp is actually added to MyClass:

enter image description here

I'm not sure if this is a problem with PostSharp or Newtonsoft JSON Schema or if I'm doing something wrong. It seems like this should be possible.

Edit 1: 20 May I split my solution out into separate projects - one for the Console app, one for the Aspect and one for MyClass. After making sure I was referencing the generated MyClass DLL directly (i.e. not a project reference, I actually removed the project once MyClass was built) it did not make a difference. AspectProp is still not in the schema. Based on this and the serialization suggested below by @dbc, this leads me to believe it is a problem with the Newtonsoft schema generator

Edit 2: 20 May Per Antonin's Answer below, I created a new ContractResolver:

public class AspectPropertyResolver : DefaultContractResolver
{
    public AspectPropertyResolver()
    {
        SerializeCompilerGeneratedMembers = true;
    }
}

And then registered it in my app before calling Generate:

gen.ContractResolver = new AspectPropertyResolver();

Now my schema includes the aspect-generated property.


Solution

  • Newtonsoft.Json has an opt-in feature to serialize compiler-generated properties. See Newtonsoft.Json.Serialization.DefaultContractResolver.SerializeCompilerGeneratedMembers property.