Skip to content

JsonSchemaGenerator

Rico Suter edited this page May 26, 2019 · 72 revisions

The JsonSchemaGenerator creates a JsonSchema (or Swagger/OpenAPI model schema) from a given C# type via reflection and the Newtonsoft.Json contract resolver:

var settings = new JsonSchemaGeneratorSettings();
var generator = new JsonSchemaGenerator(settings);
var schema = generator.Generate<Person>();

The JsonSchema.FromType() method is a shortcut to use the JsonSchemaGenerator:

var schema = JsonSchema.FromType<Person>();

To generate multiple types into the same schema, you have to reuse the schema resolver:

var settings = new JsonSchemaGeneratorSettings();

var schema = new JsonSchema(); // the schema to write into
var resolver = new JsonSchemaResolver(schema, settings); // used to add and retrieve schemas from the 'definitions'
var generator = new JsonSchemaGenerator(settings);

generator.Generate(typeof(MyRootType), schema, resolver); // generate root schema
generator.Generate(typeof(MyAdditionalType), resolver); // will be added to schema.Definitions

Provided NJsonSchema attributes

Supported C# attributes/annotations

The property name

  • Newtonsoft.Json.JsonPropertyAttribute
  • System.Runtime.Serialization.DataMemberAttribute

One of the attributes define the name of the property (JsonPropertyAttribute wins).

The property title

  • System.ComponentModel.DataAnnotations.DisplayAttribute (Name property)

The Name of the DisplayAttribute attribute is used as property title.

The property description

  • System.ComponentModel.DescriptionAttribute
  • System.ComponentModel.DataAnnotations.DisplayAttribute (Description property)
  • C# XML Documentation

Sets the description field of the property. Wins over an existing XML documentation for the property.

Define required properties

  • System.ComponentModel.DataAnnotations.RequiredAttribute

Adds the property to the list of required properties and defines the property as not nullable.

  • Newtonsoft.Json.JsonPropertyAttribute

Additionally the NullValueHandling property of the JsonPropertyAttribute defines whether the property is required (AllowNull or Always) or allows null (AllowNull).

The property validation pattern/regex

  • System.ComponentModel.DataAnnotations.RegularExpressionAttribute

Sets the pattern regex validation field for the property.

The number minimum and maximum values

  • System.ComponentModel.DataAnnotations.RangeAttribute

Sets the minimum and maximum validation fields of the property.

The string minLength and maxLength values

  • System.ComponentModel.DataAnnotations.MinLengthAttribute
  • System.ComponentModel.DataAnnotations.MaxLengthAttribute

The property must be a string.

The array minItems and maxItems values

  • System.ComponentModel.DataAnnotations.MinLengthAttribute
  • System.ComponentModel.DataAnnotations.MaxLengthAttribute

The property must be an array.

Define default values

The default value of a propery can be defined using the DefaultValueAttribute. This sets the default property of the JSON Schema and is then used in the generated DTOs while initializing the objects.

  • System.ComponentModel.DataAnnotations.DefaultValueAttribute

Define known types to include in generation

  • System.Runtime.Serialization.KnownTypeAttribute

It is also possible to define a static method which returns known types (see PR #292)

Also see Inheritance.

Integer vs string enumerations

JSON Schema supports integer and string enumerations. In Json.NET, enums are serialized as integer by default. However you can mark a property with the JsonConverterAttribute so that it is serialized as string. NJsonSchema looks for these attributes and generates the enum JSON Schema respecting this attribute:

// Only this property is serialized as string
[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }

// Always serialized as string
[JsonConverter(typeof(StringEnumConverter))]
public enum Gender
{
    ...
}

Also see Enums

Read-only property

  • System.ComponentModel.ReadOnlyAttribute

Sets the IsReadOnly property on the [JsonSchema] class and serializes to the readonly JSON Schema property (not serialized when false).

NotNullAttribute and CanBeNullAttribute

Controls if a property can be null or is not nullable, the default behavior can be changed with the DefaultReferenceTypeNullHandling setting (default: Null).

Specially handled types

System.Object, Newtonsoft.Json.Linq.JObject and ExpandoObject

Handled as "any" type (JSON type 'Object' and AllowAdditionalProperties = true), results in a dictionary.

Newtonsoft.Json.Linq.JArray

Handled as "any" array type

System.Exception

Only the properties "InnerException", "Message", "Source", "StackTrace" are generated.

System.Type

Handled as "string" (default behavior of Json.NET).

Custom type and format for class

Use the JsonSchemaAttribute to fully change the type and format attributes of the JSON Schema for a C# class:

[JsonSchema(JsonObjectType.String, Format = "point")]
public class Point
{
    public decimal X { get; set; }

    public decimal Y { get; set; }
}

public class AnnotationClass
{
    public Point Point { get; set; }
}

(You should also implement a custom class serializer for the Point class to reflect the type and format)

The JSON Schema:

{
  "$schema": "http://json-schema.org/draft-04/schema#", 
  "typeName": "AnnotationClass",
  "additionalProperties": false,
  "type": "object",
  "properties": {
    "Point": {
      "type": [
        "null",
        "string"
      ],
      "format": "point"
    }
  }
}

Ignored properties

A property is ignored when either

  1. The property is marked with the JsonIgnoreAttribute property
  2. The class has a DataContractAttribute attribute and the property has no DataMemberAttribute and no JsonPropertyAttribute