繁体   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?

我正在使用 Newtonsoft.Json.Schema package 生成 JSON 模式。 目前,模式不包含“标题”属性,因此我按照文档中的示例创建了一个自定义提供程序,但是该提供程序仅在父节点上运行并跳过所有属性节点。

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方法返回 null,它会遍历所有属性(我在调试器中观察到),尽管它没有我想要的功能
  • 如果我添加一个 if 块以在当前 context.ObjectType 具有属性时跳过,它会遍历所有属性,但只会将标题添加到第一个属性

所以我最终下载了代码并单步执行它,发现一旦你的提供者返回一个模式,它就会绕过当前节点下所有节点的所有默认处理。 所以你必须自己做所有的解析,或者以某种方式解决默认行为。 我最终创建了一个提供程序,允许您在每个节点上执行逻辑,但仍然为您提供默认生成的模式:

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

做这样的事情:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM