Skip to content

JsonSchemaGenerator

Rico Suter edited this page Jul 20, 2022 · 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(typeof(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(schema, typeof(MyRootType), resolver); // generate root schema
generator.Generate(typeof(MyAdditionalType), resolver); // will be added to schema.Definitions

System.Text.Json vs Newtonsoft.Json

By default the JsonSchemaGenerator uses the Newtonsoft.Json library rules to generate JSON Schemas. In order to use System.Text.Json rules you just have to set SerializerSettings (Newtonsoft) to null in the JsonSchemaGeneratorSettings object and provide a System.Text.Json options object in SerializerOptions instead.

Provided NJsonSchema attributes

List of all 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)
  • The summary tag of the XML Documentation

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

Example objects

See Define examples

Define required properties

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

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

Sets the property to required (must be defined) but does not change nullability, i.e. a reference type is still nullable. Use an additional [Required] attribute to make the property not nullable.

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

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
  3. It is excluded with the Newtonsoft.Json serializer contract