JSON Schema reader, generator and validator for .NET
Switch branches/tags
v7.0 v6.0 NSwag-Build-1854 NSwag-Build-1853 NSwag-Build-1852 NSwag-Build-1850 NSwag-Build-1849 NSwag-Build-1848 NSwag-Build-1847 NSwag-Build-1846 NSwag-Build-1844 NSwag-Build-1843 NSwag-Build-1841 NSwag-Build-1840 NSwag-Build-1839 NSwag-Build-1838 NSwag-Build-1837 NSwag-Build-1836 NSwag-Build-1835 NSwag-Build-1834 NSwag-Build-1833 NSwag-Build-1832 NSwag-Build-1831 NSwag-Build-1830 NSwag-Build-1829 NSwag-Build-1828 NSwag-Build-1827 NSwag-Build-1826 NSwag-Build-1825 NSwag-Build-1824 NSwag-Build-1823 NSwag-Build-1822 NSwag-Build-1821 NSwag-Build-1820 NSwag-Build-1819 NSwag-Build-1818 NSwag-Build-1817 NSwag-Build-1816 NSwag-Build-1815 NSwag-Build-1814 NSwag-Build-1813 NSwag-Build-1812 NSwag-Build-1811 NSwag-Build-1810 NSwag-Build-1809 NSwag-Build-1808 NSwag-Build-1807 NSwag-Build-1806 NSwag-Build-1805 NSwag-Build-1804 NSwag-Build-1803 NSwag-Build-1802 NSwag-Build-1801 NSwag-Build-1800 NSwag-Build-1799 NSwag-Build-1798 NSwag-Build-1797 NSwag-Build-1796 NSwag-Build-1795 NSwag-Build-1794 NSwag-Build-1793 NSwag-Build-1792 NSwag-Build-1791 NSwag-Build-1790 NSwag-Build-1789 NSwag-Build-1788 NSwag-Build-1787 NSwag-Build-1786 NSwag-Build-1785 NSwag-Build-1784 NSwag-Build-1783 NSwag-Build-1781 NSwag-Build-1780 NSwag-Build-1778 NSwag-Build-1774 NSwag-Build-1772 NSwag-Build-1770 NSwag-Build-1768 NSwag-Build-1766 NSwag-Build-1764 NSwag-Build-1762 NSwag-Build-1760 NSwag-Build-1758 NSwag-Build-1756 NSwag-Build-1754 NSwag-Build-1752 NSwag-Build-1750 NSwag-Build-1748 NSwag-Build-1746 NSwag-Build-1744 NSwag-Build-1742 NSwag-Build-1740 NSwag-Build-1738 NSwag-Build-1735 NSwag-Build-1733 NSwag-Build-1731 NSwag-Build-1729 NSwag-Build-1726 NSwag-Build-1724 NSwag-Build-1722
Nothing to show
Clone or download
Latest commit a0d077a Nov 13, 2018

README.md

NJsonSchema for .NET

NuGet Version Build status Build status Gitter StackOverflow Wiki

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:

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