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

如何在MVC视图模型的自定义验证器中获取当前Action名称?

获取共享视图模型对应的当前Action名称(自定义验证器场景)

当然可以!不管你用的是ASP.NET Core还是传统ASP.NET MVC,都能在自定义验证器里拿到当前触发的Action名称,下面分场景给你具体实现方案:

ASP.NET Core 场景

方法1:通过 ActionContextAccessor 自动获取

首先得在项目的服务容器里注册这个访问器(.NET 6+ 在 Program.cs,老版本在 Startup.cs):

// .NET 6+ Program.cs
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

然后在你的自定义验证器里,直接从验证上下文里获取这个服务,就能拿到Action名称了:

public class MyCustomValidator : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // 从验证上下文获取ActionContextAccessor
        var actionContextAccessor = validationContext.GetService<IActionContextAccessor>();
        if (actionContextAccessor?.ActionContext == null)
        {
            return ValidationResult.Success;
        }

        // 精准获取Action名称(从路由值里拿)
        var currentAction = actionContextAccessor.ActionContext.ActionDescriptor.RouteValues["action"];

        // 这里根据Action名称写你的验证逻辑
        if (currentAction == "Create" && value == null)
        {
            return new ValidationResult("创建操作时该字段不能为空");
        }

        return ValidationResult.Success;
    }
}

方法2:手动传递Action名称到视图模型

如果不想依赖框架上下文,也可以在Controller的Action里手动把当前Action名称赋值给视图模型的一个属性:

// 先给视图模型加个属性
public class SharedViewModel
{
    public string CurrentAction { get; set; }
    // 其他共享属性...
}

// 在Controller的Action里赋值
public IActionResult Create(SharedViewModel model)
{
    model.CurrentAction = "Create";
    if (ModelState.IsValid)
    {
        // 业务逻辑...
    }
    return View(model);
}

// 自定义验证器里直接用这个属性
public class MyCustomValidator : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var model = validationContext.ObjectInstance as SharedViewModel;
        if (model?.CurrentAction == "Create" && value == null)
        {
            return new ValidationResult("创建操作时该字段不能为空");
        }
        return ValidationResult.Success;
    }
}

传统ASP.NET MVC 场景

在老版本MVC里,可以通过HttpContextBase获取路由数据里的Action名称:

public class MyCustomValidator : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // 获取HttpContext
        var httpContext = validationContext.GetService(typeof(HttpContextBase)) as HttpContextBase;
        if (httpContext == null)
        {
            return ValidationResult.Success;
        }

        // 从路由数据里拿Action名称
        var currentAction = httpContext.Request.RequestContext.RouteData.Values["action"].ToString();

        // 验证逻辑
        if (currentAction == "Edit" && value == null)
        {
            return new ValidationResult("编辑操作时该字段不能为空");
        }

        return ValidationResult.Success;
    }
}

额外:FluentValidation 场景

如果你用的是FluentValidation做验证,同样可以注入ActionContextAccessor来获取Action名称:

public class SharedViewModelValidator : AbstractValidator<SharedViewModel>
{
    private readonly IActionContextAccessor _actionContextAccessor;

    public SharedViewModelValidator(IActionContextAccessor actionContextAccessor)
    {
        _actionContextAccessor = actionContextAccessor;

        RuleFor(x => x.MyProperty)
            .NotEmpty()
            .When(_ => 
            {
                var currentAction = _actionContextAccessor.ActionContext?.ActionDescriptor.RouteValues["action"];
                return currentAction == "Create";
            });
    }
}

简单总结下:自动获取的方式更省心,适合大多数场景;手动传递的方式更可控,避免依赖框架上下文。你可以根据自己的项目情况选最合适的方案~

内容的提问来源于stack exchange,提问作者Thorkil Værge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:35:59