如何通过数据注解用正则验证字符串列表并在Swagger中正确显示?
问题:让Swagger正确为List的元素生成正则验证Schema
我定义了Detail类,其中包含类型为List<string>的parameters属性,使用自定义RegularExpressionListAttribute数据注解对列表中的每个字符串进行正则验证,同时设置了MaxLength(50)。通过Swagger生成该类的JSON Schema时,发现正则表达式被应用在了数组层级而非数组内的字符串项上。需要在不将列表改为对象列表的前提下,让正则表达式正确显示在Swagger的Schema中。
代码示例
C# 实体类与自定义注解
public class Detail { public int index { get; set; } [MaxLength(50)] [RegularExpressionList("^[a-zA-Z0-9א-ת@/\\.\\- !@#$%&*()_+]*$")] public List<string> parameters { get; set; } = new List<string>(); } public class RegularExpressionListAttribute : RegularExpressionAttribute { public RegularExpressionListAttribute(string pattern) : base(pattern) { } public override bool IsValid(object value) { if (value is not IEnumerable<string>) return false; foreach (var val in value as IEnumerable<string>) { if (!Regex.IsMatch(val, Pattern)) return false; } return true; } }
当前生成的Swagger Schema片段
"Detail": { "type": "object", "properties": { "index": { "type": "integer", "format": "int32" }, "parameters": { "pattern": "^[a-zA-Z0-9א-ת@/\\.\\- !@#$%&*()_+]*$", "maxItems": 50, "type": "array", "items": { "type": "string" }, "nullable": true } }, "additionalProperties": false }
解决方案
自定义Swagger Schema过滤器
创建一个ISchemaFilter实现类,识别自定义的RegularExpressionListAttribute,将正则规则从数组层级转移到数组元素的Schema上:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System.ComponentModel.DataAnnotations; using System.Reflection; public class RegularExpressionListSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { // 获取属性上的RegularExpressionListAttribute var regexAttr = context.MemberInfo? .GetCustomAttributes(typeof(RegularExpressionListAttribute), false) .Cast<RegularExpressionListAttribute>() .FirstOrDefault(); if (regexAttr != null && schema.Type == "array" && schema.Items != null) { // 将正则表达式赋值给数组元素的Schema schema.Items.Pattern = regexAttr.Pattern; // 移除数组层级的正则规则 schema.Pattern = null; } // 可选:如果需要将MaxLength从数组元素数量改为单个字符串长度 // 取消下面注释,并将实体类的[MaxLength(50)]改为[StringLength(50)] /* var stringLengthAttr = context.MemberInfo? .GetCustomAttributes(typeof(StringLengthAttribute), false) .Cast<StringLengthAttribute>() .FirstOrDefault(); if (stringLengthAttr != null && schema.Type == "array" && schema.Items?.Type == "string") { schema.Items.MaxLength = stringLengthAttr.MaximumLength; schema.MaxItems = null; } */ } }
注册过滤器
在项目的Program.cs(或Startup.cs)中,将自定义过滤器添加到Swagger配置:
builder.Services.AddSwaggerGen(c => { // 注册自定义Schema过滤器 c.SchemaFilter<RegularExpressionListSchemaFilter>(); });
最终生成的正确Schema
调整后,Swagger会将正则规则正确应用到数组的字符串元素上:
"Detail": { "type": "object", "properties": { "index": { "type": "integer", "format": "int32" }, "parameters": { "maxItems": 50, "type": "array", "items": { "type": "string", "pattern": "^[a-zA-Z0-9א-ת@/\\.\\- !@#$%&*()_+]*$" }, "nullable": true } }, "additionalProperties": false }
内容的提问来源于stack exchange,提问作者Nir Amir
相关产品推荐
相关产品推荐

