如何从类型的给定属性中找到相应的 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? */]
            }
        }
    }
}

我在 Generator 上发现了 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.
}

还有其他想法吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)