简体   繁体   English

如何创建自定义 JSchemaGenerationProvider 以将 title 属性添加到 model 和模型的属性?

[英]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:其他注意事项:

  • if you return null from the provider 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,它会遍历所有属性(我在调试器中观察到),尽管它没有我想要的功能
  • if I add in an if block to skip when the current context.ObjectType has properties, it does iterate through all the properties, but only adds the title to the first property如果我添加一个 if 块以在当前 context.ObjectType 具有属性时跳过,它会遍历所有属性,但只会将标题添加到第一个属性

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支持DisplayNameAttributeDescriptionAttribute Placing those on a type or property will add title and description properties to the generated schema. 将它们放置在类型或属性上将向生成的模式添加titledescription属性。

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.

相关问题 如何使用由 model 属性组成的参数创建自定义验证属性 - How to create a custom validation attribute with parameters consisting of model properties 如何使用模型中的自定义属性来更改剃刀视图模型中的输入元素名称属性值? - How can I change the input element name attribute value in a razor view model using a custom attribute in a model? 使用textboxfor时,如何从扩展属性访问模型属性? - How can I access the model properties from extended attribute when using textboxfor? 定制模型活页夹可以双向使用吗? - Can custom model binders work in both directions? 如何为Code-first模型类创建自定义属性? - How to create a custom attribute for Code-first model class? 如何在MVC中为模型中的数据创建模板,而不是整个模型? - How in MVC can I create a template for data on a model but not the entire model? 如何在Linq查询中使用模型属性? - How can I use my model properties in a Linq query? 用于检查我的模型属性中的重复项的自定义验证属性未触发 - Custom validation attribute to check for duplicates among my model properties is not firing 如何在viewmodel中检测模型中属性的更改? - How can I dectect changes in properties inside my model in viewmodel? 如何将 Model 的选定属性绑定到 Razor 页面? - How can I bind selected properties of a Model to a Razor Page?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM