基于JSON字符串构建JSON Schema:.NET下Json.NET相关技术求助
从JSON实例生成JSON Schema(Json.NET兼容方案)
我完全懂你现在的困扰——想用Newtonsoft Json.NET从实际的JSON文档自动生成对应的JSON Schema,但JSchema.Parse()只能处理本身就是Schema格式的字符串,根本满足不了从业务JSON实例推导Schema的需求。之前尝试结合JsonSchema4库也没搞定,对吧?
下面给你两个实用的解决方案,都是和Json.NET兼容的:
方案一:用NJsonSchema库(推荐,功能完整)
NJsonSchema是专门用来处理JSON Schema的第三方库,和Newtonsoft.Json集成非常好,能自动从JSON实例推导Schema,支持复杂类型、嵌套结构、格式验证等。
步骤1:安装NuGet包
用.NET CLI安装:
dotnet add package NJsonSchema
或者Package Manager控制台:
Install-Package NJsonSchema
步骤2:代码示例
using NJsonSchema; using Newtonsoft.Json.Linq; using System; class Program { static void Main() { // 你的JSON实例字符串 string jsonInstance = @"{ ""Id"": 1, ""Name"": ""Alice"", ""IsActive"": true, ""Email"": ""alice@example.com"", ""Addresses"": [ { ""Street"": ""123 Main St"", ""City"": ""New York"" } ] }"; // 解析JSON实例为JObject JObject jsonObject = JObject.Parse(jsonInstance); // 从JSON实例生成Schema(异步方法,这里用.GetAwaiter().GetResult()简化,实际项目建议用await) var schema = JsonSchema.FromJsonAsync(jsonObject.ToString()).GetAwaiter().GetResult(); // 把Schema转为格式化的JSON字符串(指定Draft7标准) string schemaJson = schema.ToJson(SchemaType.JsonSchemaDraft7); Console.WriteLine(schemaJson); } }
这段代码会生成包含类型、嵌套对象、数组结构的完整Schema,还能自动识别常见格式(比如邮箱会被标记为"format": "email")。
方案二:自定义简单生成逻辑(适合基础场景)
如果不想引入第三方库,你可以自己写一个递归方法,遍历JSON的结构,根据值的类型生成对应的JSchema片段:
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Schema; using System.Collections.Generic; public static class SchemaGenerator { public static JSchema GenerateFromJson(JToken jsonToken) { var schema = new JSchema(); switch (jsonToken.Type) { case JTokenType.Object: schema.Type = JSchemaType.Object; schema.Properties = new Dictionary<string, JSchema>(); foreach (JProperty prop in jsonToken.Children<JProperty>()) { schema.Properties[prop.Name] = GenerateFromJson(prop.Value); // 如果需要标记字段为必填,取消下面的注释 // schema.Required.Add(prop.Name); } break; case JTokenType.Array: schema.Type = JSchemaType.Array; var firstItem = jsonToken.First; if (firstItem != null) { schema.Items.Add(GenerateFromJson(firstItem)); } break; case JTokenType.String: schema.Type = JSchemaType.String; // 可以手动添加格式验证,比如判断是否是邮箱/日期 if (IsEmail(jsonToken.Value<string>())) { schema.Format = "email"; } break; case JTokenType.Integer: schema.Type = JSchemaType.Integer; break; case JTokenType.Float: schema.Type = JSchemaType.Number; break; case JTokenType.Boolean: schema.Type = JSchemaType.Boolean; break; case JTokenType.Null: schema.Type = JSchemaType.Null; break; default: schema.Type = JSchemaType.String; break; } return schema; } // 简单的邮箱判断辅助方法 private static bool IsEmail(string input) { return !string.IsNullOrEmpty(input) && input.Contains("@"); } } // 使用示例 string jsonInstance = @"{ /* 你的JSON内容 */ }"; JObject jsonObject = JObject.Parse(jsonInstance); JSchema customSchema = SchemaGenerator.GenerateFromJson(jsonObject); string schemaString = customSchema.ToString();
这个方法的优势是轻量,但局限性也很明显:只能处理基础类型和简单嵌套,复杂的格式验证、枚举、条件规则等需要自己扩展。
补充说明
你之前尝试的JsonSchema4其实是NJsonSchema的旧版本,现在NJsonSchema是它的迭代升级版本,维护更活跃,功能更完善,建议优先使用它。
内容的提问来源于stack exchange,提问作者msalafia
相关产品推荐
相关产品推荐

