NJsonSchema icon indicating copy to clipboard operation
NJsonSchema copied to clipboard

Additional properties from ContractResolver not included in schema.

Open alphaleonis opened this issue 3 years ago • 0 comments

When using a custom ContractResolver (with Newtonsoft.Json), it seems that when the contract is modified with additional properties these do not show up in the schema generated by JsonSchemaGenerator. Is there something I'm missing here?

Here is a sample program illustrating the problem:

   class Program
   {
      static void Main(string[] args)
      {
         JsonSerializerSettings settings = new JsonSerializerSettings()
         {
            ContractResolver = new MyContractResolver(),
            Formatting = Formatting.Indented
         };

         Console.WriteLine(JsonConvert.SerializeObject(new MyClass() { Name = "Homer" }, settings));

         JsonSchemaGenerator generator = new JsonSchemaGenerator(new JsonSchemaGeneratorSettings() { SerializerSettings = settings });
         var schema = generator.Generate(typeof(MyClass));
         Console.WriteLine(schema.ToJson());

      }
   }

   public class MyClass
   {
      public string Name { get; set; }
   }

   class MyContractResolver : DefaultContractResolver
   {
      protected override JsonContract CreateContract(Type objectType)
      {         
         if (objectType != typeof(MyClass))
            return base.CreateContract(objectType);

         var contract = base.CreateObjectContract(objectType);
         contract.Properties.Add(new JsonProperty()
         {
            PropertyName = "Additional",
            PropertyType = typeof(string),
            DeclaringType = typeof(MyClass),
            Readable = true,
            Writable = true,
            ValueProvider = new MyValueProvider()

         });

         return contract;
      }

      private class MyValueProvider : IValueProvider
      {
         public object GetValue(object target) => "Some Value";

         public void SetValue(object target, object value)
         {
         }
      }
   }

The json from the serialization looks as expected:

{
  "Name": "Homer",
  "Additional": "Some Value"
}

But the schema is missing the Additional property:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "MyClass",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "Name": {
      "type": [
        "null",
        "string"
      ]
    }
  }
}

I was under the impression that the ContractResolver was used to determine the schema. If I remove properties from the contract they seem to be removed from the schema as well though, so not sure what's going on here?

alphaleonis avatar Oct 19 '21 13:10 alphaleonis