using System.Collections.ObjectModel; namespace LinkToolAddin.common; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text.Json; public static class JsonSchemaGenerator { public static string GenerateJsonSchema(MethodInfo methodInfo) { var parameters = methodInfo.GetParameters(); var properties = new Dictionary(); var required = new List(); foreach (var param in parameters) { var paramName = param.Name ?? throw new InvalidOperationException("参数没有名称。"); var paramSchema = GenerateSchemaForType(param.ParameterType); properties[paramName] = paramSchema; if (!param.IsOptional) { required.Add(paramName); } } var schemaRoot = new Dictionary { { "$schema", "http://json-schema.org/draft-07/schema#" }, { "type", "object" }, { "properties", properties } }; if (required.Count > 0) { schemaRoot["required"] = required; } var options = new JsonSerializerOptions { WriteIndented = true }; return JsonSerializer.Serialize(schemaRoot, options); } private static object GenerateSchemaForType(Type type) { // 处理可空类型 if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { var underlyingType = Nullable.GetUnderlyingType(type); return new[] { GenerateSchemaForType(underlyingType), "null" }; } // 处理集合类型(数组或IEnumerable) if (IsCollectionType(type, out Type elementType)) { return new Dictionary { { "type", "array" }, { "items", GenerateSchemaForType(elementType) } }; } // 处理基本类型(int, string, bool, etc.) if (IsPrimitiveType(type)) { string jsonType = MapClrTypeToJsonType(type); var schema = new Dictionary { { "type", jsonType } }; if (type == typeof(DateTime)) schema["format"] = "date-time"; else if (type == typeof(Guid)) schema["format"] = "uuid"; return schema; } // 处理复杂类型(类、结构体) if (type.IsClass || type.IsValueType) { var props = new Dictionary(); foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { props[prop.Name] = GenerateSchemaForType(prop.PropertyType); } return new Dictionary { { "type", "object" }, { "properties", props } }; } // 默认情况 return new Dictionary { { "type", "any" } }; } private static bool IsCollectionType(Type type, out Type elementType) { if (type == typeof(string)) { elementType = null; return false; } if (type.IsArray) { elementType = type.GetElementType(); return true; } if (type.IsGenericType) { var genericTypeDef = type.GetGenericTypeDefinition(); if (genericTypeDef == typeof(IEnumerable<>) || genericTypeDef == typeof(List<>) || genericTypeDef == typeof(Collection<>)) { elementType = type.GetGenericArguments()[0]; return true; } } elementType = null; return false; } private static bool IsPrimitiveType(Type type) { return type.IsPrimitive || type == typeof(string) || type == typeof(decimal) || type == typeof(DateTime) || type == typeof(Guid); } private static string MapClrTypeToJsonType(Type type) { if (type == typeof(int) || type == typeof(short) || type == typeof(long) || type == typeof(uint) || type == typeof(ushort) || type == typeof(ulong)) return "integer"; if (type == typeof(float) || type == typeof(double) || type == typeof(decimal)) return "number"; if (type == typeof(bool)) return "boolean"; if (type == typeof(string)) return "string"; if (type == typeof(DateTime) || type == typeof(Guid)) return "string"; return "any"; } }