Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use JSON.NET to generate JSON schema with extra attributes

I am using JSON.NET to generate JSON Schema from c# object class. But I was unable to add any other json schema attributes e.g. maxLength, pattern(regex to validate email), etc

Below is my working code, I can only generate json schema with required attribute. It would be great if anyone can post some code example about how to add those extra attribute for json schema.

Thanks,

my code example

public class Customer
{
    [JsonProperty(Required = Required.Always)]
    public int CustomerID { get; set; }

    [JsonProperty(Required = Required.Always)]
    public string FirstName { get; set; }

    [JsonProperty(Required = Required.Always)]
    public string LastName { get; set; }

    [JsonProperty(Required = Required.Always)]
    public string Email { get; set; }

    [JsonProperty(Required = Required.AllowNull)]
    public string Phone { get; set; }
}

to

{
    "title" : "Customer",
    "type" : "object",
    "properties" : {
        "CustomerID" : {
            "required" : true,
            "type" : "integer"
        },
        "FirstName" : {
            "required" : true,
            "type" : "string"
        },
        "LastName" : {
            "required" : true,
            "type" : "string"
        },
        "Email" : {
            "required" : true,
            "type" : "string"
        },
        "Phone" : {
            "required" : true,
            "type" : [
                "string",
                "null"
            ]
        }
    }
}
like image 491
Yoh Avatar asked Apr 23 '12 08:04

Yoh


People also ask

Is JSON net schema free?

Json.NET has this functionality. It is, there's a free (albeit somewhat limited - 1k validations/hr) version under the AGPL.

What is $ref in JSON Schema?

In a JSON schema, a $ref keyword is a JSON Pointer to a schema, or a type or property in a schema. A JSON pointer takes the form of A # B in which: A is the relative path from the current schema to a target schema. If A is empty, the reference is to a type or property in the same schema, an in-schema reference.

How do I set a schema in JSON?

At the top of the file, you can specify the schema's id, the schema that should be used to validate the format of your schema, and a descriptive title. These are all defined using the keywords id, $schema and title, all of which are provided in the draft JSON Schema.


2 Answers

James Newton-King is right in his answer, I'll just expand it with a code example so people stumbling onto this page don't need to study the whole documentation.

So you can use the attributes provided with .NET to specify those addidional options, like maximum length of the string or allowed regex pattern. Here are some examples:

public class MyDataModel
{
    public enum SampleEnum { EnumPosition1, EnumPosition2, EnumPosition3 }

    [JsonProperty(Required = Required.Always)]
    [RegularExpression(@"^[0-9]+$")]
    public string PatternTest { get; set; }

    [JsonProperty(Required = Required.Always)]
    [MaxLength(3)]
    public string MaxLength3 { get; set; }

    [JsonProperty(Required = Required.AllowNull)]
    [EnumDataType(typeof(SampleEnum))]
    public string EnumProperty { get; set; }
}

The annotations above come from System.ComponentModel.DataAnnotations namespace.

To make those additional attributes affect resulting json schema, you need to use JSchemaGenerator class distributed with Json.NET Schema package. If you use older JsonSchemaGenerator, then some upgrade is needed, as it's now deprecated and does not contain new functions like the aforementioned.

Here's a sample function that generates Json Schema for the class above:

    /// <summary>
    /// Generates JSON schema for a given C# class using Newtonsoft.Json.Schema library.
    /// </summary>
    /// <param name="myType">class type</param>
    /// <returns>a string containing JSON schema for a given class type</returns>
    internal static string GenerateSchemaForClass(Type myType)
    {
        JSchemaGenerator jsonSchemaGenerator = new JSchemaGenerator();
        JSchema schema = jsonSchemaGenerator.Generate(myType);
        schema.Title = myType.Name;

        return schema.ToString();
    }

and you can use it just like this:

 string schema = GenerateSchemaForClass(typeof(MyDataModel));
like image 145
Paweł Bulwan Avatar answered Oct 19 '22 23:10

Paweł Bulwan


Json.NET Schema now has much improved schema generation support.

You can annotate properties with .NET's Data Annotation attributes to specify information like minimum, maximum, minLength, maxLength and more on a schema.

There is also JSchemaGenerationProvider that lets you take complete control when generating a schema for a type.

More details here: http://www.newtonsoft.com/jsonschema/help/html/GeneratingSchemas.htm

like image 44
James Newton-King Avatar answered Oct 20 '22 00:10

James Newton-King