You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:26:20