• Stars
    star
    1,325
  • Rank 34,124 (Top 0.7 %)
  • Language
    C#
  • License
    MIT License
  • Created over 9 years ago
  • Updated 11 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JSON Schema reader, generator and validator for .NET

NJsonSchema for .NET

NSwag | NJsonSchema | Apimundo | Namotion.Reflection

Azure DevOps Nuget MyGet Discord StackOverflow Wiki Apimundo

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 and Namotion.Reflection for additional .NET reflection APIs.

NuGet packages:

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

Preview NuGet Feed: https://www.myget.org/F/njsonschema/api/v3/index.json

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.

Some code generators can directly be used via the Apimundo service.

NJsonSchema usage

The JsonSchema class can be used as follows:

var schema = JsonSchema.FromType<Person>();
var schemaData = schema.ToJson();
var errors = schema.Validate("{...}");

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

schema = await JsonSchema.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:

More Repositories

1

NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
C#
6,500
star
2

DNT

DNT (DotNetTools): Command line tools to manage .NET projects and solutions.
C#
397
star
3

MyToolkit

MyToolkit for .NET
C#
335
star
4

VisualJsonEditor

A JSON schema based file editor for Windows.
C#
333
star
5

NuGetReferenceSwitcher

Visual Studio extension to switch between NuGet and project references.
C#
207
star
6

Namotion.Reflection

.NET library with advanced reflection APIs.
C#
202
star
7

SigSpec

Specification and code generator for SignalR Core.
C#
156
star
8

ProjectDependencyBrowser

Application to browse, sort, filter and launch your Visual Studio projects.
C#
46
star
9

Namotion.Messaging

.NET abstractions and implementations for message brokers, event queues and data ingestion services.
C#
46
star
10

Namotion.Storage

.NET abstractions and implementations for storage services like blob storages, file systems or object storages.
C#
35
star
11

PowerCmd

PowerCmd: The Windows Prompt replacement.
C#
33
star
12

NConsole

NConsole is a .NET library to parse command line arguments and execute commands.
C#
31
star
13

HomeBlaze

Home Automation with .NET/Blazor
C#
12
star
14

DotNetMicroservice

C#
11
star
15

InsideAsyncAwait

C#
8
star
16

aurelia-bs

Bootstrap UI (CSS framework) components for Aurelia JS.
TypeScript
7
star
17

ShopOnCore

C#
7
star
18

AureliaBootstrapDialogs

JavaScript
6
star
19

SampleOutputProcessorActionFilter

Sample application for a blog article.
C#
5
star
20

ScopeCheckingNinjectKernel

C#
3
star
21

DockerDemo

ASP.NET Core with Docker sample and tutorial
C#
3
star
22

SampleWcfService

Sample application for a blog article.
C#
3
star
23

VistoJS

Visto JavaScript Framework (VistoJS)
TypeScript
2
star
24

SampleSortableChildCollectionForm

Sample ASP.NET MVC application with edit form for an entity with a collection property.
CSS
2
star
25

SampleEfMigrationsApplication

C#
2
star
26

RicoSuter

1
star
27

SampleProjectRepository

Sample projects for package and dependency management tests.
C#
1
star
28

MdFileWiki

C#
1
star