在 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.
}
还有其他想法吗?