JSON Schema draft v4 reader, generator and validator for .NET
C# Batchfile
Switch branches/tags
v7.0 v6.0 NSwag-Build-990 NSwag-Build-988 NSwag-Build-987 NSwag-Build-984 NSwag-Build-983 NSwag-Build-982 NSwag-Build-981 NSwag-Build-980 NSwag-Build-979 NSwag-Build-978 NSwag-Build-977 NSwag-Build-976 NSwag-Build-975 NSwag-Build-974 NSwag-Build-973 NSwag-Build-972 NSwag-Build-971 NSwag-Build-970 NSwag-Build-969 NSwag-Build-968 NSwag-Build-967 NSwag-Build-966 NSwag-Build-965 NSwag-Build-964 NSwag-Build-963 NSwag-Build-962 NSwag-Build-961 NSwag-Build-960 NSwag-Build-959 NSwag-Build-958 NSwag-Build-957 NSwag-Build-956 NSwag-Build-955 NSwag-Build-954 NSwag-Build-953 NSwag-Build-952 NSwag-Build-951 NSwag-Build-950 NSwag-Build-949 NSwag-Build-948 NSwag-Build-947 NSwag-Build-946 NSwag-Build-945 NSwag-Build-944 NSwag-Build-943 NSwag-Build-942 NSwag-Build-941 NSwag-Build-940 NSwag-Build-939 NSwag-Build-938 NSwag-Build-937 NSwag-Build-936 NSwag-Build-935 NSwag-Build-934 NSwag-Build-933 NSwag-Build-932 NSwag-Build-931 NSwag-Build-930 NSwag-Build-929 NSwag-Build-928 NSwag-Build-927 NSwag-Build-926 NSwag-Build-925 NSwag-Build-924 NSwag-Build-923 NSwag-Build-922 NSwag-Build-921 NSwag-Build-920 NSwag-Build-919 NSwag-Build-918 NSwag-Build-917 NSwag-Build-916 NSwag-Build-915 NSwag-Build-914 NSwag-Build-913 NSwag-Build-912 NSwag-Build-911 NSwag-Build-910 NSwag-Build-909 NSwag-Build-908 NSwag-Build-907 NSwag-Build-906 NSwag-Build-905 NSwag-Build-904 NSwag-Build-903 NSwag-Build-902 NSwag-Build-901 NSwag-Build-900 NSwag-Build-899 NSwag-Build-898 NSwag-Build-897 NSwag-Build-896 NSwag-Build-895 NSwag-Build-894 NSwag-Build-893 NSwag-Build-892 NSwag-Build-891 NSwag-Build-890
Nothing to show
Latest commit f8c5a43 Aug 18, 2017 @RSuter committed on GitHub Merge pull request #448 from SumoServer/fix/stack-overflow
Fix for stack overflow on Linux.

README.md

NJsonSchema for .NET

NuGet Version Build status Build status Gitter StackOverflow

NJsonSchema is a .NET library to read, generate and validate JSON Schema draft v4 schemas. The library can read a schema from a file or string and validate JSON data against it. A schema can also be generated from an existing .NET class. With the code generation APIs you can generate C# and TypeScript classes or interfaces from a schema.

The library uses Json.NET to read and write JSON data.

NuGet packages:

The NuGet packages may require the Microsoft.NETCore.Portable.Compatibility package on .NET Core/UWP targets (if mscorlib is missing).

CI NuGet Feed: https://www.myget.org/gallery/njsonschema-ci

Features:

  • Read existing JSON Schemas and validate JSON data (JsonSchema4.FromJsonAsync())
  • Generate JSON Schema from .NET type via reflection (with support for many attributes/annotations) (JsonSchema4.FromTypeAsync<MyType>())
  • Generate JSON Schema from sample JSON data (JsonSchema4.FromData())
  • Support for schema references ($ref) (relative, URL and file)
  • Generate C# and TypeScript code from JSON Schema
  • Support for .NET Core (via PCL 259 / .NET Standard 1.0, also see XML Documentation)

NJsonSchema is heavily used in NSwag, a Swagger API toolchain for .NET which generates client code for Web API services. NSwag also provides command line tools to use the NJsonSchema's JSON Schema generator (command types2swagger).

The project is developed and maintained by Rico Suter and other contributors.

NJsonSchema usage

The JsonSchema4 class can be used as follows:

var schema = await JsonSchema4.FromTypeAsync<Person>();
var schemaData = schema.ToJson();
var errors = schema.Validate("{...}");

foreach (var error in errors)
    Console.WriteLine(error.Path + ": " + error.Kind);

schema = await JsonSchema4.FromJsonAsync(schemaData);

The Person class:

public class Person
{
    [Required]
    public string FirstName { get; set; }

    public string MiddleName { get; set; }

    [Required]
    public string LastName { get; set; }

    public Gender Gender { get; set; }

    [Range(2, 5)]
    public int NumberWithRange { get; set; }

    public DateTime Birthday { get; set; }

    public Company Company { get; set; }

    public Collection<Car> Cars { get; set; }
}

public enum Gender
{
    Male,
    Female
}

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

    public Company Manufacturer { get; set; }
}

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

The generated JSON schema data stored in the schemaData variable:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Person",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "FirstName",
    "LastName"
  ],
  "properties": {
    "FirstName": {
      "type": "string"
    },
    "MiddleName": {
      "type": [
        "null",
        "string"
      ]
    },
    "LastName": {
      "type": "string"
    },
    "Gender": {
      "oneOf": [
        {
          "$ref": "#/definitions/Gender"
        }
      ]
    },
    "NumberWithRange": {
      "type": "integer",
      "format": "int32",
      "maximum": 5.0,
      "minimum": 2.0
    },
    "Birthday": {
      "type": "string",
      "format": "date-time"
    },
    "Company": {
      "oneOf": [
        {
          "$ref": "#/definitions/Company"
        },
        {
          "type": "null"
        }
      ]
    },
    "Cars": {
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "#/definitions/Car"
      }
    }
  },
  "definitions": {
    "Gender": {
      "type": "integer",
      "description": "",
      "x-enumNames": [
        "Male",
        "Female"
      ],
      "enum": [
        0,
        1
      ]
    },
    "Company": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "Name": {
          "type": [
            "null",
            "string"
          ]
        }
      }
    },
    "Car": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "Name": {
          "type": [
            "null",
            "string"
          ]
        },
        "Manufacturer": {
          "oneOf": [
            {
              "$ref": "#/definitions/Company"
            },
            {
              "type": "null"
            }
          ]
        }
      }
    }
  }
}

NJsonSchema.CodeGeneration usage

The NJsonSchema.CodeGeneration can be used to generate C# or TypeScript code from a JSON schema:

var generator = new CSharpGenerator(schema);
var file = generator.GenerateFile();

The file variable now contains the C# code for all the classes defined in the JSON schema.

TypeScript

The previously generated JSON Schema would generate the following TypeScript interfaces.

Settings:

new TypeScriptGeneratorSettings { TypeStyle = TypeScriptTypeStyle.Interface, TypeScriptVersion = 2.0m }

Output:

export enum Gender {
    Male = 0, 
    Female = 1, 
}

export interface Company {
    Name: string | undefined;
}

export interface Car {
    Name: string | undefined;
    Manufacturer: Company | undefined;
}

export interface Person {
    FirstName: string;
    MiddleName: string | undefined;
    LastName: string;
    Gender: Gender;
    NumberWithRange: number;
    Birthday: Date;
    Company: Company | undefined;
    Cars: Car[] | undefined;
}

... and the following TypeScript classes.

Settings:

new TypeScriptGeneratorSettings { TypeStyle = TypeScriptTypeStyle.Class, TypeScriptVersion = 2.0m }

Output:

export enum Gender {
    Male = 0, 
    Female = 1, 
}

export class Company implements ICompany {
    name: string | undefined;

    constructor(data?: ICompany) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.name = data["Name"];
        }
    }

    static fromJS(data: any): Company {
        let result = new Company();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["Name"] = this.name;
        return data; 
    }
}

export interface ICompany {
    name: string | undefined;
}

export class Car implements ICar {
    name: string | undefined;
    manufacturer: Company | undefined;

    constructor(data?: ICar) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.name = data["Name"];
            this.manufacturer = data["Manufacturer"] ? Company.fromJS(data["Manufacturer"]) : <any>undefined;
        }
    }

    static fromJS(data: any): Car {
        let result = new Car();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["Name"] = this.name;
        data["Manufacturer"] = this.manufacturer ? this.manufacturer.toJSON() : <any>undefined;
        return data; 
    }
}

export interface ICar {
    name: string | undefined;
    manufacturer: Company | undefined;
}

export class Person implements IPerson {
    firstName: string;
    middleName: string | undefined;
    lastName: string;
    gender: Gender;
    numberWithRange: number;
    birthday: Date;
    company: Company | undefined;
    cars: Car[] | undefined;

    constructor(data?: IPerson) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.firstName = data["FirstName"];
            this.middleName = data["MiddleName"];
            this.lastName = data["LastName"];
            this.gender = data["Gender"];
            this.numberWithRange = data["NumberWithRange"];
            this.birthday = data["Birthday"] ? new Date(data["Birthday"].toString()) : <any>undefined;
            this.company = data["Company"] ? Company.fromJS(data["Company"]) : <any>undefined;
            if (data["Cars"] && data["Cars"].constructor === Array) {
                this.cars = [];
                for (let item of data["Cars"])
                    this.cars.push(Car.fromJS(item));
            }
        }
    }

    static fromJS(data: any): Person {
        let result = new Person();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["FirstName"] = this.firstName;
        data["MiddleName"] = this.middleName;
        data["LastName"] = this.lastName;
        data["Gender"] = this.gender;
        data["NumberWithRange"] = this.numberWithRange;
        data["Birthday"] = this.birthday ? this.birthday.toISOString() : <any>undefined;
        data["Company"] = this.company ? this.company.toJSON() : <any>undefined;
        if (this.cars && this.cars.constructor === Array) {
            data["Cars"] = [];
            for (let item of this.cars)
                data["Cars"].push(item.toJSON());
        }
        return data; 
    }
}

export interface IPerson {
    firstName: string;
    middleName: string | undefined;
    lastName: string;
    gender: Gender;
    numberWithRange: number;
    birthday: Date;
    company: Company | undefined;
    cars: Car[] | undefined;
}

Final notes

Applications which use the library:

  • VisualJsonEditor, a JSON schema based file editor for Windows.
  • NSwag: The Swagger API toolchain for .NET