如何创建自定义 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"
//  ]
//}

如何在 属性 节点上将此提供程序配置为 运行(类似于链接文档中提供的示例)?

其他注意事项:

所以我最终下载了代码并逐步执行它,发现一旦您的提供商 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支持DisplayNameAttributeDescriptionAttribute。将它们放在类型或 属性 上会将 titledescription 属性添加到生成的架构中。

类型:

[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