using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Text;
public partial class JSON2Class_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnGo_Click(object sender, EventArgs e)
{
JObject jo =
JsonConvert.DeserializeObject<JObject>(txtJson.Value);
JsonClassParser.RegisterClass(jo, "Root");
txtClass.Value = JsonClassParser.GenClassCode();
}
}
public class JsonClassParser
{
public class RawClass
{
public string ClassName;
public string PropertyHash;
public Dictionary<string, string> Properties;
}
//蒐集所有類別
public static List<RawClass> Library
= new List<RawClass>();
private static string getCLSType(JTokenType t)
{
switch (t)
{
case JTokenType.Boolean:
return "bool";
case JTokenType.Bytes:
return "byte[]";
case JTokenType.Date:
return "DateTime";
case JTokenType.Float:
return "decimal";
case JTokenType.Integer:
return "int";
case JTokenType.String:
return "string";
default:
throw new ApplicationException(
t.ToString() + " is not supported");
}
}
//註冊類別
public static string RegisterClass(JObject jo, string className)
{
RawClass c = new RawClass();
c.ClassName = "C" +
className ??
Path.GetFileNameWithoutExtension(
Path.GetTempFileName());
//將所有類別組成Hash字串,用以比對類別是否相同
c.PropertyHash =
string.Join(",",
jo.Properties().Select(o => o.Name).ToArray());
c.Properties = new Dictionary<string, string>();
foreach (JProperty p in jo.Properties())
{
string t = "";
switch (p.Value.Type)
{
case JTokenType.Object:
t = RegisterClass((JObject)jo[p.Name], p.Name);
break;
case JTokenType.Array:
JArray ary = (JArray)jo[p.Name];
string typeName = null;
foreach (JToken jv in ary)
{
if (jv.Type == JTokenType.Array)
throw new ApplicationException(
"Array of array is not supported!");
string s =
jv.Type == JTokenType.Object ?
RegisterClass((JObject)jv, p.Name) :
getCLSType(jv.Type);
if (typeName == null)
typeName = s;
else if (typeName != s)
throw new ApplicationException(
"Complex array is not supported!");
}
t = typeName + "[]";
break;
case JTokenType.Boolean:
case JTokenType.Date:
case JTokenType.Float:
case JTokenType.Integer:
case JTokenType.String:
t = getCLSType(p.Value.Type);
break;
default:
throw new ApplicationException(
p.Type.ToString() + " is not supported!");
}
c.Properties.Add(p.Name, t);
}
//檢查是否已有重覆類別存在
var q = (from o in Library
where o.PropertyHash == c.PropertyHash
select o).SingleOrDefault();
//不存在時新增
if (q == null)
{
Library.Add(c);
return c.ClassName;
}
else //存在時傳回既有類別
return q.ClassName;
}
public static string GenClassCode()
{
StringBuilder sb = new StringBuilder();
foreach (RawClass rc in Library)
{
sb.AppendFormat("public class {0} {{\r\n", rc.ClassName);
foreach (string p in rc.Properties.Keys)
{
sb.AppendFormat(" public {0} {1} {{ get; set; }}\r\n",
rc.Properties[p], p);
}
sb.AppendLine("}");
}
return sb.ToString();
}
}