From 5aacc4e42b07b4beb1f8afc56b4065f0d19472b4 Mon Sep 17 00:00:00 2001 From: Milkey Tan <24996957+mili-tan@users.noreply.github.com> Date: Mon, 30 Dec 2024 23:27:25 +0800 Subject: [PATCH 1/2] Update JsonSchema.ToJsonSchema --- src/Models/JsonSchema.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Models/JsonSchema.cs b/src/Models/JsonSchema.cs index 3ab4966..9a5f5a5 100644 --- a/src/Models/JsonSchema.cs +++ b/src/Models/JsonSchema.cs @@ -143,4 +143,5 @@ public class Item /// [JsonPropertyName("type")] public string? Type { get; set; } + /// Gets or sets a list of required fields within the schema. } From ebf83524029e981469aff14abcb0341c4ed2dadd Mon Sep 17 00:00:00 2001 From: Milkey Tan <24996957+mili-tan@users.noreply.github.com> Date: Mon, 30 Dec 2024 23:28:00 +0800 Subject: [PATCH 2/2] Update JsonSchema.ToJsonSchema --- src/Models/JsonSchema.cs | 97 ++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 29 deletions(-) diff --git a/src/Models/JsonSchema.cs b/src/Models/JsonSchema.cs index 9a5f5a5..09ffced 100644 --- a/src/Models/JsonSchema.cs +++ b/src/Models/JsonSchema.cs @@ -33,40 +33,64 @@ public class JsonSchema /// /// Get the JsonSchema from Type, use typeof(Class) to get the Type of Class. /// - public static JsonSchema ToJsonSchema(Type type) { - var required = new List(); - var properties = new Dictionary(); - foreach (var property in type.GetProperties()) - { - var propertyName = property.Name; - var propertyType = property.PropertyType; - - var isEnumerable = type.IsArray || (typeof(IEnumerable).IsAssignableFrom(propertyType) && propertyType != typeof(string)); - var isNullable = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); - - properties.Add(propertyName, - new Property - { - Type = GetTypeName(propertyType), - Items = isEnumerable - ? new Item - { - Type = GetTypeName(propertyType.IsArray - ? propertyType.GetElementType() - : propertyType.GetGenericArguments().First()) - } - : null - }); - - if (!isNullable) - required.Add(propertyName); - } + var properties = type.GetProperties().ToDictionary( + prop => prop.Name, + prop => new Property + { + Type = GetTypeName(prop.PropertyType), + Items = typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string) + ? new Item + { + Type = IsPrimitiveType(prop.PropertyType.IsArray + ? prop.PropertyType.GetElementType() + : prop.PropertyType.GetGenericArguments().First()) + ? GetTypeName(prop.PropertyType.IsArray + ? prop.PropertyType.GetElementType() + : prop.PropertyType.GetGenericArguments().First()) + : "object", + Properties = IsPrimitiveType(prop.PropertyType.IsArray + ? prop.PropertyType.GetElementType() + : prop.PropertyType.GetGenericArguments().First()) + ? null + : ToJsonSchema(prop.PropertyType.IsArray + ? prop.PropertyType.GetElementType() + : prop.PropertyType.GetGenericArguments().First()).Properties, + Required = IsPrimitiveType(prop.PropertyType.IsArray + ? prop.PropertyType.GetElementType() + : prop.PropertyType.GetGenericArguments().First()) + ? null + : (prop.PropertyType.IsArray + ? prop.PropertyType.GetElementType() + : prop.PropertyType.GetGenericArguments().First()).GetProperties() + .Where(info => + !info.PropertyType.IsGenericType || + info.PropertyType.GetGenericTypeDefinition() != typeof(Nullable<>) || + Nullable.GetUnderlyingType(info.PropertyType) != null) + .Select(info => info.Name) + .ToList() + } + : null + } + ); + + var required = type.GetProperties() + .Where(prop => + !prop.PropertyType.IsGenericType || + prop.PropertyType.GetGenericTypeDefinition() != typeof(Nullable<>) || + Nullable.GetUnderlyingType(prop.PropertyType) != null) + .Select(prop => prop.Name) + .ToList(); return new JsonSchema { Properties = properties, Required = required }; } + private static bool IsPrimitiveType(Type type) + { + return type.IsPrimitive || type == typeof(string) || type == typeof(decimal); + } + private static string GetTypeName(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) @@ -94,6 +118,7 @@ private static string GetTypeName(Type type) return "number"; case TypeCode.Boolean: return "boolean"; + case TypeCode.DateTime: case TypeCode.String: return "string"; case TypeCode.Object: @@ -141,7 +166,21 @@ public class Item /// /// Gets or sets the type of the item. /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("type")] public string? Type { get; set; } - /// Gets or sets a list of required fields within the schema. + + /// + /// Gets or sets the properties of the item. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("properties")] + public Dictionary? Properties { get; set; } + + /// + /// Gets or sets a list of required fields within the item. + /// + [JsonPropertyName("required")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public IEnumerable? Required { get; set; } }