使用Newtonsoft.Json.Schema序列化JSchema依赖项失败求助
我遇到过类似的问题,Newtonsoft.Json.Schema 在序列化 Dependencies 时有时候会因为 Schema 的构造细节或者版本问题导致关键字不输出。结合你的代码和期望输出,这里有几个解决建议:
1. 确保依赖的子 Schema 明确设置类型
JSON Schema 中 properties 关键字仅对 object 类型的实例生效,虽然语法上允许不指定 type,但 Newtonsoft.Json.Schema 的序列化器可能会忽略缺少 type 的 Schema 中的属性。给你的 oneOf1、oneOf2 加上 Type = JSchemaType.Object:
var oneOf1 = new JSchema() { Type = JSchemaType.Object }; oneOf1.Properties.Add("ShowField", new JSchema() { Enum = { false } }); var oneOf2 = new JSchema() { Type = JSchemaType.Object }; oneOf2.Properties.Add("ShowField", new JSchema() { Enum = { true } }); oneOf2.Properties.Add("ExtraField", new JSchema() { Type = JSchemaType.String });
2. 使用 JSchemaWriter 显式序列化
有时候直接调用 ToString() 可能会使用默认的序列化设置,导致某些关键字被忽略。改用 JSchemaWriter 来序列化,确保所有关键字都被正确输出:
var schema = new JSchema() { Type = JSchemaType.Object, SchemaVersion = new Uri("http://json-schema.org/draft-07/schema#") }; schema.Properties.Add("ShowField", new JSchema() { Type = JSchemaType.Boolean }); var oneOf1 = new JSchema() { Type = JSchemaType.Object }; oneOf1.Properties.Add("ShowField", new JSchema() { Enum = { false } }); var oneOf2 = new JSchema() { Type = JSchemaType.Object }; oneOf2.Properties.Add("ShowField", new JSchema() { Enum = { true } }); oneOf2.Properties.Add("ExtraField", new JSchema() { Type = JSchemaType.String }); var oneOf = new JSchema(); oneOf.OneOf.Add(oneOf1); oneOf.OneOf.Add(oneOf2); schema.Dependencies.Add("ShowField", oneOf); // 使用 JSchemaWriter 序列化 var writer = new JSchemaWriter(); string serializedSchema = writer.Write(schema); Console.WriteLine(serializedSchema);
3. 检查 Newtonsoft.Json.Schema 版本
旧版本的 Newtonsoft.Json.Schema(比如 1.x 系列)存在一些序列化的 bug,尤其是对 dependencies 和 oneOf 这类复合关键字的支持。确保你使用的是最新的稳定版本(目前是 3.x),可以通过 NuGet 更新:
Install-Package Newtonsoft.Json.Schema -Version 3.0.15
问题原因分析
你已经正确将依赖项添加到 schema.Dependencies 字典中,但序列化时未输出,大概率是因为子 Schema 缺少 type 声明,导致序列化器认为这些 Schema 是“空的”或者无效的,进而忽略了整个 dependencies 块。加上 Type = JSchemaType.Object 后,序列化器会正确识别这些 Schema 的结构,从而输出 dependencies 关键字。
内容的提问来源于stack exchange,提问作者eivindjk

