Asp.Net Web API中SwaggerUI自定义ValidationAttribute客户端验证失效
解决方案:自定义精确字符串长度验证属性及Swagger UI客户端验证配置
一、修复继承StringLengthAttribute时的自定义错误消息问题
你直接将ErrorMessage赋值为资源名称nameof(ValidationMessages.ExactStringLength),但ErrorMessage是直接显示的文本,并非资源键,这导致自定义消息无法被正确解析。同时需确保MinimumLength和MaximumLength都设为目标长度,让验证逻辑严格匹配精确长度。
修改后的代码:
/// <summary> /// Specifies the exact length of characters that are allowed in a data field. /// </summary> public class ExactStringLengthAttribute : StringLengthAttribute { public ExactStringLengthAttribute(int length) : base(length) { MinimumLength = length; // 正确配置本地化资源错误消息 ErrorMessageResourceName = nameof(ValidationMessages.ExactStringLength); ErrorMessageResourceType = typeof(ValidationMessages); } }
注意:确保ValidationMessages.resx资源文件中存在ExactStringLength条目,内容需包含占位符,例如:"{0}必须恰好是{1}个字符"({0}对应属性名称,{1}对应设定的长度值)。
二、修复继承ValidationAttribute时无错误消息的问题
你的代码存在两处核心问题:一是构造函数使用lambda方式传入资源文本,无法正确触发本地化解析;二是EnsureLegalLengths方法抛出的空异常会中断验证逻辑。以下是修正后的完整代码:
/// <summary> /// Specifies the exact length of characters that are allowed in a data field. /// </summary> [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] public class ExactStringLengthAttribute : ValidationAttribute { public ExactStringLengthAttribute(int length) : base(nameof(ValidationMessages.ExactStringLength)) { Length = length; // 明确配置资源参数 ErrorMessageResourceName = nameof(ValidationMessages.ExactStringLength); ErrorMessageResourceType = typeof(ValidationMessages); } public int Length { get; } public override bool IsValid(object? value) { EnsureLegalLengths(); if (value == null) return true; // 增加类型检查,避免强制转换异常 if (value is not string strValue) throw new InvalidOperationException("该验证属性仅适用于字符串类型"); return strValue.Length == Length; } public override string FormatErrorMessage(string name) { EnsureLegalLengths(); return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, Length); } private void EnsureLegalLengths() { if (Length < 0) throw new InvalidOperationException("验证长度不能为负数"); } }
关键修改点:
- 替换构造函数的lambda传参方式,明确配置
ErrorMessageResourceName和ErrorMessageResourceType - 增加字符串类型检查,避免非字符串属性触发异常
- 给
EnsureLegalLengths方法的异常添加有意义的提示文本 - 确保资源文件中的错误消息包含
{0}(属性名)和{1}(长度)占位符
三、Swagger UI客户端验证配置
要让Swagger UI识别自定义的ExactStringLengthAttribute并生成客户端验证规则,需添加SchemaFilter映射约束:
- 配置SwaggerGen(在
Program.cs或Startup.cs中):
builder.Services.AddSwaggerGen(c => { // 启用数据注解支持 c.EnableAnnotations(); // 注册自定义SchemaFilter c.SchemaFilter<ExactStringLengthSchemaFilter>(); });
- 实现
ExactStringLengthSchemaFilter类:
public class ExactStringLengthSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var exactLengthAttr = context.MemberInfo?.GetCustomAttribute<ExactStringLengthAttribute>(); if (exactLengthAttr != null) { // 将精确长度映射为Swagger的minLength和maxLength约束 schema.MinLength = exactLengthAttr.Length; schema.MaxLength = exactLengthAttr.Length; // 可选:在Schema描述中添加提示文本 schema.Description += $" (必须恰好是{exactLengthAttr.Length}个字符)"; } } }
配置完成后,Swagger UI会自动为带有ExactStringLengthAttribute的属性生成客户端验证规则,在「Try it out」功能中会实时校验输入长度。
内容的提问来源于stack exchange,提问作者THE NORMAL
相关产品推荐
相关产品推荐

