Skip to content

Instantly share code, notes, and snippets.

@RhysC
Created October 31, 2014 02:55
Show Gist options
  • Save RhysC/480e7a758639a3215701 to your computer and use it in GitHub Desktop.
Save RhysC/480e7a758639a3215701 to your computer and use it in GitHub Desktop.
Code generator from JSON Schema - swap out the impl of ObjectDef to write, view model, dtos etc
using System;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Schema;
namespace JsonSchemaToCode
{
public class CSharpObjectDefinition : ObjectDefinition
{
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("public class ");
sb.AppendLine(Name);
sb.AppendLine("{");
foreach (var item in Properties)
{
sb.Append("public ");
sb.Append(item.Value);
sb.Append(" ");
sb.Append(item.Key);
sb.AppendLine(" { get; set; }");
}
sb.AppendLine("}");
return sb.ToString();
}
public override string GetTypeFromSchema(JsonSchema jsonSchema)
{
const string nullable = "?";
switch (jsonSchema.Type)
{
case JsonSchemaType.Array:
if (jsonSchema.Items.Count == 0)
return "IEnumerable<object>";
if (jsonSchema.Items.Count == 1)
return String.Format("IEnumerable<{0}>", GetTypeFromSchema(jsonSchema.Items.First()));
throw new Exception("Not sure what type this will be.");
case JsonSchemaType.Boolean:
return String.Format("bool{0}", jsonSchema.Required.HasValue && jsonSchema.Required.Value ? String.Empty : nullable);
case JsonSchemaType.Float:
return String.Format("float{0}", jsonSchema.Required.HasValue && jsonSchema.Required.Value ? String.Empty : nullable);
case JsonSchemaType.Integer:
return String.Format("int{0}", jsonSchema.Required.HasValue && jsonSchema.Required.Value ? String.Empty : nullable);
case JsonSchemaType.String:
return "string";
case JsonSchemaType.Object:
throw new ArgumentException("Object type should be mnage by the base type");
default:
return "object";
}
}
}
}
using System;
using System.IO;
using Newtonsoft.Json.Schema;
namespace JsonSchemaToCode
{
class Program
{
static void Main()
{
string schemaText;
using (var r = new StreamReader(@"C:\Schema.txt"))
{
schemaText = r.ReadToEnd();
}
var jsonSchema = JsonSchema.Parse(schemaText);
if (jsonSchema != null)
{
var def = new SchemaGenerator<KnockOutJsObjectDefinition>(jsonSchema);
var code = def.ToString();
Console.WriteLine(code);
}
Console.ReadLine();
}
}
}
using System;
using System.Text;
using Newtonsoft.Json.Schema;
namespace JsonSchemaToCode
{
public class KnockOutJsObjectDefinition : ObjectDefinition
{
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("var ");
sb.Append(Name);
sb.AppendLine(" = function() {");
sb.AppendLine("var self = this;");
foreach (var item in Properties)
{
sb.Append("self.");
sb.Append(item.Key);
sb.Append(item.Value);
sb.AppendLine(";");
}
sb.AppendLine("};");
return sb.ToString();
}
public override string GetTypeFromSchema(JsonSchema jsonSchema)
{
var str = " = ko.observable()";
if (jsonSchema.Required.GetValueOrDefault())
{
str += ".extend({ required: true })";
}
switch (jsonSchema.Type)
{
case JsonSchemaType.Array:
return " = ko.observableArray()";
case JsonSchemaType.Float:
str += ".extend({ number: true })";
break;
case JsonSchemaType.Integer:
str += ".extend({ digit: true })";
break;
case JsonSchemaType.Object:
throw new ArgumentException("Object type should be mnage by the base type");
}
return str;
}
}
}
using System.Collections.Generic;
using Newtonsoft.Json.Schema;
namespace JsonSchemaToCode
{
public abstract class ObjectDefinition
{
public string Name { get; set; }
public Dictionary<string, string> Properties { get; set; }
public abstract string GetTypeFromSchema(JsonSchema jsonSchema);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Schema;
namespace JsonSchemaToCode
{
internal class SchemaGenerator<T> where T : ObjectDefinition, new()
{
public List<T> ObjectDefinitions { get; private set; }
public SchemaGenerator(JsonSchema schema)
{
ObjectDefinitions = new List<T>();
ConvertJsonSchemaToModel(schema);
}
private void ConvertJsonSchemaToModel(JsonSchema schema)
{
if (schema.Type == null)
throw new Exception("Schema does not specify a type.");
switch (schema.Type)
{
case JsonSchemaType.Object:
CreateTypeFromSchema(schema);
break;
case JsonSchemaType.Array:
foreach (var item in schema.Items.Where(x => x.Type.HasValue && x.Type == JsonSchemaType.Object))
{
CreateTypeFromSchema(item);
}
break;
}
}
private T CreateTypeFromSchema(JsonSchema schema)
{
var def = new T
{
Name = String.Format("Poco_{0}", Guid.NewGuid().ToString().Replace("-", String.Empty)),
Properties = schema.Properties.ToDictionary(item => item.Key.Trim(), item => GetTypeFromSchema(item.Value))
};
ObjectDefinitions.Add(def);
return def;
}
private string GetTypeFromSchema(JsonSchema jsonSchema)
{
if (jsonSchema.Type != JsonSchemaType.Object)
return new T().GetTypeFromSchema(jsonSchema);
var def = CreateTypeFromSchema(jsonSchema);
return def.Name;
}
public override string ToString()
{
var sb = new StringBuilder();
foreach (var objectDefinition in ObjectDefinitions)
{
sb.AppendLine(objectDefinition.ToString());
}
return sb.ToString();
}
}
}
@krisrok
Copy link

krisrok commented Nov 1, 2014

may be worth a repository/library :)

@RhysC
Copy link
Author

RhysC commented Feb 3, 2015

Note : JSON.Net is not going to be supporting v4 JamesNK/Newtonsoft.Json#115 (comment)
Will looks to pull this new lib in and make a tool out of this.

@RhysC
Copy link
Author

RhysC commented Feb 3, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment