自定义ValidationAttribute下FormNoValidate属性失效问题及优化咨询
ASP.NET自定义验证属性忽略带
formnovalidate提交按钮的实现方案 我在ASP.NET中创建了一个自定义验证属性,整体表现良好,但遇到以下问题:表单中有多个提交按钮,其中一个删除按钮设置了formnovalidate属性,然而点击该按钮时自定义验证仍会触发,阻碍UI流程。我猜测需在自定义验证类中检查触发验证的按钮是否带有该属性?
简化代码示例
模型类
[CustomValidation(ErrorMessage = "Please Select a choice")] public List<SelectListItem> Foo { get; set; }
视图代码
<button type="submit" class="btn btn-danger" formnovalidate="formnovalidate" name="command" value="Delete" title="Delete"> Delete </button>
自定义验证类
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] public class CustomValidation : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // 测试用占位逻辑,非真实业务逻辑 if (value != null) { return ValidationResult.Success; } else { return new ValidationResult(this.ErrorMessage); } } }
更新
我通过限制仅当按下的不是删除按钮时才检查ModelState.IsValid,暂时解决了问题。这或许是可行方案,但如果能在验证上下文中直接判断是否执行验证逻辑,会是更简洁的解决办法。
更优实现方案
要在自定义验证属性内部完成判断,可通过ValidationContext获取HTTP上下文,检查提交的按钮标识来决定是否跳过验证:
修改自定义验证类的IsValid方法:
protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // 获取HttpContext服务 var httpContextAccessor = validationContext.GetService(typeof(IHttpContextAccessor)) as IHttpContextAccessor; if (httpContextAccessor?.HttpContext != null) { // 读取提交的command参数(对应按钮的name属性值) var submittedCommand = httpContextAccessor.HttpContext.Request.Form["command"]; // 若为Delete按钮提交,直接返回验证通过 if (submittedCommand == "Delete") { return ValidationResult.Success; } } // 原有验证逻辑 if (value != null) { return ValidationResult.Success; } else { return new ValidationResult(this.ErrorMessage); } }
注意:需要先在项目中注册IHttpContextAccessor服务,在Startup.cs或Program.cs中添加:
services.AddHttpContextAccessor();
这种方式将验证逻辑与按钮判断内聚在属性类中,无需在控制器中额外处理ModelState.IsValid的触发条件,结构更简洁。
内容的提问来源于stack exchange,提问作者da_jokker
相关产品推荐
相关产品推荐

