[英]How can I create a custom JSchemaGenerationProvider that adds a title attribute to both the model and to the model's properties?
I am using the Newtonsoft.Json.Schema package to generate JSON Schemas.我正在使用 Newtonsoft.Json.Schema package 生成 JSON 模式。 Currently, the schemas contain no 'title' property, so I created a custom provider following the example in the documentation , however the provider only runs on the parent node and skips all the property nodes.目前,模式不包含“标题”属性,因此我按照文档中的示例创建了一个自定义提供程序,但是该提供程序仅在父节点上运行并跳过所有属性节点。
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"
// ]
//}
How do I configure this provider to run on property nodes (similar to the example provided in the linked documentation)?如何配置此提供程序以在属性节点上运行(类似于链接文档中提供的示例)?
Other Notes:其他注意事项:
GetSchema
method, it does iterate over all the properties (which I observed in debugger), though it doesn't have the functionality I want then如果您从提供者GetSchema
方法返回 null,它会遍历所有属性(我在调试器中观察到),尽管它没有我想要的功能So I ended up downloading the code and stepping through it and found that once your provider returns a schema it bypasses all of the default processing for all nodes below the current node. 所以我最终下载了代码并单步执行它,发现一旦你的提供者返回一个模式,它就会绕过当前节点下所有节点的所有默认处理。 So pretty much you have to do all the parsing yourself, or work around the default behavior somehow. 所以你必须自己做所有的解析,或者以某种方式解决默认行为。 I ended up creating a provider that allows you to execute your logic on each node but still gives you the default generated schema to work with: 我最终创建了一个提供程序,允许您在每个节点上执行逻辑,但仍然为您提供默认生成的模式:
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;
}
}
The latest version of Json.NET Schema supports DisplayNameAttribute
and DescriptionAttribute
. 最新版本的Json.NET Schema支持DisplayNameAttribute
和DescriptionAttribute
。 Placing those on a type or property will add title
and description
properties to the generated schema. 将它们放置在类型或属性上将向生成的模式添加title
和description
属性。
Type: 类型:
[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; }
}
Code: 码:
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 https://www.newtonsoft.com/jsonschema/help/html/GenerateWithDescriptions.htm
Do something like this:做这样的事情:
class FormatSchemaProvider : JSchemaGenerationProvider
{
public override JSchema GetSchema(JSchemaTypeGenerationContext context)
{
if (context.ObjectType == typeof(Sprite) || context.ObjectType == typeof(AudioClip) || context.ObjectType == typeof(GameObject) || context.ObjectType == typeof(Vector3))
{
JSchema schema = new JSchema
{
Title = context.SchemaTitle,
Description = context.SchemaDescription,
Type = JSchemaType.String
};
return schema;
}
return null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.