asp.net-core - 如何从类型的给定属性中找到相应的 JsonSchema 属性?
问题描述
在 OpenAPI 中,您可以为字符串数组中的项目指定 maxLength。使用 DataAnnotations,您不能开箱即用地执行此操作,因此我为它创建了一个相当通用的自定义 ValidationAttribute(这是我现在要做的,只是为了让它工作)。
public class ArrayItemValidationAttribute : ValidationAttribute
{
public ValidationAttribute ItemValidator { get; }
public ArrayItemValidationAttribute(Type validatorType, params object[] args)
{
if (!typeof(ValidationAttribute).IsAssignableFrom(validatorType))
{
throw new Exception("The given validatorType does not derive from ValidationAttribute.");
}
ItemValidator = (ValidationAttribute)Activator.CreateInstance(validatorType, args);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (!(value is Array array))
{
return new ValidationResult("Property is not an Array type.");
}
foreach (var item in array)
{
var vr = ItemValidator.GetValidationResult(item, validationContext);
if (vr != null)
{
return new ValidationResult(vr.ErrorMessage);
}
}
return ValidationResult.Success;
}
}
我现在想将此传播到 OpenAPI 规范,该规范是使用 NSwag 从代码生成的。我正在使用 ISchemaProcessor,但我不知道如何从 Type 属性获取 JsonSchema 属性。
public class ArrayItemValidationProcessor : ISchemaProcessor
{
public void Process(SchemaProcessorContext context)
{
foreach (var property in context.Type.GetProperties())
{
var attr = property.GetCustomAttribute<ArrayItemValidationAttribute>();
if (attr != null)
{
context.Schema.Properties[/* What to fill in here? */]
}
}
}
}
我在生成器上发现了 GetPropertyName,但这需要一个 JsonProperty 对象,所以我仍然遇到同样的问题。
我可以尝试自己从实际的属性名称和/或 JsonPropertyAttribute 数据中派生 json 模式属性名称,但如果实现会在未来版本中更改/扩展,我不想更新此代码,它应该继续工作.
编辑:到目前为止我能想到的最好的是:
var jsonProperty = context.Settings.ResolveContract(context.Type) is JsonObjectContract contract
? contract.Properties.SingleOrDefault(x => x.UnderlyingName == property.Name)
: null;
var propName = context.Generator.GetPropertyName(jsonProperty, property.ToContextualMember());
if (context.Schema.Properties.TryGetValue(propName, out var jsonSchemaProperty) && jsonSchemaProperty.IsArray) {
// put maxLength on schema here.
}
还有其他想法吗?
解决方案
推荐阅读
- quartz.net - Quartz 的较低日志级别
- linux - 调用 ttymxc 上的打开函数时的 rcu_preempt
- unity3d - Unity - 创建 Android 菜单项(3 个垂直点和返回箭头按钮)
- apache - .htaccess 规则将爬虫重定向到另一个文件夹
- python - use python request to load more items
- elasticsearch - 动态映射大于 2^63 - 1 的数值字段数据类型(long 类型)
- url-routing - TYPO3 9.5 URL Routing with URL Segment is not working
- javascript - 如何从 Vue.js 中的模板调用方法?
- c# - Application Gets Slow After Enable/Disable MDIChldren
- php - Use a function declared in a different file [PHP-HTML]