如何创建自定义 JSchemaGenerationProvider 以将 title 属性添加到模型和模型的属性中?
How can I create a custom JSchemaGenerationProvider that adds a title attribute to both the model and to the model's properties?
我正在使用 Newtonsoft.Json.Schema 包生成 JSON 模式。目前,模式不包含 'title' 属性,因此我在 the example in the documentation 之后创建了一个自定义提供程序,但是该提供程序仅 运行 在 parent 节点上并跳过所有 属性 个节点。
class User {
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedDate { get; set; }
}
class TitleProvider : JSchemaGenerationProvider {
public override JSchema GetSchema(JSchemaTypeGenerationContext context) {
var schema = new JSchemaGenerator().Generate(context.ObjectType);
schema.Title = "foo";
return schema;
}
}
public class Program {
public static void Main() {
var generator = new JSchemaGenerator();
generator.GenerationProviders.Add(new TitleProvider());
var schema = generator.Generate(typeof(User));
Console.WriteLine(schema);
}
}
// OUTPUT:
//{
// "title": "foo",
// "type": "object",
// "properties": {
// "Id": {
// "type": "integer"
// },
// "Name": {
// "type": [
// "string",
// "null"
// ]
// },
// "CreatedDate": {
// "type": "string"
// }
// },
// "required": [
// "Id",
// "Name",
// "CreatedDate"
// ]
//}
如何在 属性 节点上将此提供程序配置为 运行(类似于链接文档中提供的示例)?
其他注意事项:
- 如果您从提供程序
GetSchema
方法中 return null,它会遍历所有属性(我在调试器中观察到),尽管它没有我想要的功能然后
- 如果我添加一个 if 块以在当前 context.ObjectType 具有属性时跳过,它会遍历所有属性,但只会将标题添加到第一个 属性
所以我最终下载了代码并逐步执行它,发现一旦您的提供商 returns 一个架构,它就会绕过当前节点下所有节点的所有默认处理。所以几乎所有的解析都必须自己完成,或者以某种方式解决默认行为。我最终创建了一个提供程序,它允许您在每个节点上执行您的逻辑,但仍然为您提供默认生成的模式以供使用:
abstract class RecursiveProvider : JSchemaGenerationProvider {
public string SkipType { get; set; }
public override JSchema GetSchema(JSchemaTypeGenerationContext context) {
var type = context.ObjectType;
JSchema schema = null;
var generator = new JSchemaGenerator();
Console.WriteLine(type.Name);
var isObject = type.Namespace != "System";
if (isObject) {
if (SkipType == type.Name)
return null;
this.SkipType = type.Name;
generator.GenerationProviders.Add(this);
}
schema = generator.Generate(type);
return ModifySchema(schema, context);
}
public abstract JSchema ModifySchema(JSchema schema, JSchemaTypeGenerationContext context);
}
class PropertyProvider : RecursiveProvider {
public override JSchema ModifySchema(JSchema schema, JSchemaTypeGenerationContext context) {
schema.Title = "My Title";
return schema;
}
}
最新版本Json.NET Schema支持DisplayNameAttribute
和DescriptionAttribute
。将它们放在类型或 属性 上会将 title
和 description
属性添加到生成的架构中。
类型:
[DisplayName("Postal Address")]
[Description("The mailing address.")]
public class PostalAddress
{
[DisplayName("Street Address")]
[Description("The street address. For example, 1600 Amphitheatre Pkwy.")]
public string StreetAddress { get; set; }
[DisplayName("Locality")]
[Description("The locality. For example, Mountain View.")]
public string AddressLocality { get; set; }
[DisplayName("Region")]
[Description("The region. For example, CA.")]
public string AddressRegion { get; set; }
[DisplayName("Country")]
[Description("The country. For example, USA. You can also provide the two letter ISO 3166-1 alpha-2 country code.")]
public string AddressCountry { get; set; }
[DisplayName("Postal Code")]
[Description("The postal code. For example, 94043.")]
public string PostalCode { get; set; }
}
代码:
JSchemaGenerator generator = new JSchemaGenerator();
generator.DefaultRequired = Required.DisallowNull;
JSchema schema = generator.Generate(typeof(PostalAddress));
// {
// "title": "Postal Address",
// "description": "The mailing address.",
// "type": "object",
// "properties": {
// "StreetAddress": {
// "title": "Street Address",
// "description": "The street address. For example, 1600 Amphitheatre Pkwy.",
// "type": "string"
// },
// "AddressLocality": {
// "title": "Locality",
// "description": "The locality. For example, Mountain View.",
// "type": "string"
// },
// "AddressRegion": {
// "title": "Region",
// "description": "The region. For example, CA.",
// "type": "string"
// },
// "AddressCountry": {
// "title": "Country",
// "description": "The country. For example, USA. You can also provide the two-letter ISO 3166-1 alpha-2 country code.",
// "type": "string"
// },
// "PostalCode": {
// "title": "Postal Code",
// "description": "The postal code. For example, 94043.",
// "type": "string"
// }
// }
// }
https://www.newtonsoft.com/jsonschema/help/html/GenerateWithDescriptions.htm
我正在使用 Newtonsoft.Json.Schema 包生成 JSON 模式。目前,模式不包含 'title' 属性,因此我在 the example in the documentation 之后创建了一个自定义提供程序,但是该提供程序仅 运行 在 parent 节点上并跳过所有 属性 个节点。
class User {
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedDate { get; set; }
}
class TitleProvider : JSchemaGenerationProvider {
public override JSchema GetSchema(JSchemaTypeGenerationContext context) {
var schema = new JSchemaGenerator().Generate(context.ObjectType);
schema.Title = "foo";
return schema;
}
}
public class Program {
public static void Main() {
var generator = new JSchemaGenerator();
generator.GenerationProviders.Add(new TitleProvider());
var schema = generator.Generate(typeof(User));
Console.WriteLine(schema);
}
}
// OUTPUT:
//{
// "title": "foo",
// "type": "object",
// "properties": {
// "Id": {
// "type": "integer"
// },
// "Name": {
// "type": [
// "string",
// "null"
// ]
// },
// "CreatedDate": {
// "type": "string"
// }
// },
// "required": [
// "Id",
// "Name",
// "CreatedDate"
// ]
//}
如何在 属性 节点上将此提供程序配置为 运行(类似于链接文档中提供的示例)?
其他注意事项:
- 如果您从提供程序
GetSchema
方法中 return null,它会遍历所有属性(我在调试器中观察到),尽管它没有我想要的功能然后 - 如果我添加一个 if 块以在当前 context.ObjectType 具有属性时跳过,它会遍历所有属性,但只会将标题添加到第一个 属性
所以我最终下载了代码并逐步执行它,发现一旦您的提供商 returns 一个架构,它就会绕过当前节点下所有节点的所有默认处理。所以几乎所有的解析都必须自己完成,或者以某种方式解决默认行为。我最终创建了一个提供程序,它允许您在每个节点上执行您的逻辑,但仍然为您提供默认生成的模式以供使用:
abstract class RecursiveProvider : JSchemaGenerationProvider {
public string SkipType { get; set; }
public override JSchema GetSchema(JSchemaTypeGenerationContext context) {
var type = context.ObjectType;
JSchema schema = null;
var generator = new JSchemaGenerator();
Console.WriteLine(type.Name);
var isObject = type.Namespace != "System";
if (isObject) {
if (SkipType == type.Name)
return null;
this.SkipType = type.Name;
generator.GenerationProviders.Add(this);
}
schema = generator.Generate(type);
return ModifySchema(schema, context);
}
public abstract JSchema ModifySchema(JSchema schema, JSchemaTypeGenerationContext context);
}
class PropertyProvider : RecursiveProvider {
public override JSchema ModifySchema(JSchema schema, JSchemaTypeGenerationContext context) {
schema.Title = "My Title";
return schema;
}
}
最新版本Json.NET Schema支持DisplayNameAttribute
和DescriptionAttribute
。将它们放在类型或 属性 上会将 title
和 description
属性添加到生成的架构中。
类型:
[DisplayName("Postal Address")]
[Description("The mailing address.")]
public class PostalAddress
{
[DisplayName("Street Address")]
[Description("The street address. For example, 1600 Amphitheatre Pkwy.")]
public string StreetAddress { get; set; }
[DisplayName("Locality")]
[Description("The locality. For example, Mountain View.")]
public string AddressLocality { get; set; }
[DisplayName("Region")]
[Description("The region. For example, CA.")]
public string AddressRegion { get; set; }
[DisplayName("Country")]
[Description("The country. For example, USA. You can also provide the two letter ISO 3166-1 alpha-2 country code.")]
public string AddressCountry { get; set; }
[DisplayName("Postal Code")]
[Description("The postal code. For example, 94043.")]
public string PostalCode { get; set; }
}
代码:
JSchemaGenerator generator = new JSchemaGenerator();
generator.DefaultRequired = Required.DisallowNull;
JSchema schema = generator.Generate(typeof(PostalAddress));
// {
// "title": "Postal Address",
// "description": "The mailing address.",
// "type": "object",
// "properties": {
// "StreetAddress": {
// "title": "Street Address",
// "description": "The street address. For example, 1600 Amphitheatre Pkwy.",
// "type": "string"
// },
// "AddressLocality": {
// "title": "Locality",
// "description": "The locality. For example, Mountain View.",
// "type": "string"
// },
// "AddressRegion": {
// "title": "Region",
// "description": "The region. For example, CA.",
// "type": "string"
// },
// "AddressCountry": {
// "title": "Country",
// "description": "The country. For example, USA. You can also provide the two-letter ISO 3166-1 alpha-2 country code.",
// "type": "string"
// },
// "PostalCode": {
// "title": "Postal Code",
// "description": "The postal code. For example, 94043.",
// "type": "string"
// }
// }
// }
https://www.newtonsoft.com/jsonschema/help/html/GenerateWithDescriptions.htm