根据 ASP.NET 核心中的控制器有条件要求

Conditional required based on Controller in ASP.NET Core

我想写条件要求,但条件取决于使用它的控制器。

我已经有自定义属性 MyRequiredIfNot。我只是不知道如何在 IsValid 方法中获取有关控制器的信息。

例如:

public class MyController1 : Controller
{
    public ActionResult Method1(MyModel model)
    { 
      //Name is required !!!
    }
}

public class MyController2 : MyController1 
{
    public ActionResult SomeMethod(MyModel model)
    { 
       //Name is NOT required !!!
    }
}

public class MyModel
{
    [MyRequiredIfNot(MyController2)
    public string Name { get;set; }
}

缺少实现:

public class MyRequiredIfNotAttribute : ValidationAttribute
{
    public MyRequiredIfNotAttribute(Controller controller) { }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (/*came_from ?*/ is this.controller)          //Missing !!!!
            return ValidationResult.Success;
        else
            return base.IsValid(value, validationContext);
    }
}

要检索 Controller,您可以尝试 IActionContextAccessor

按照以下步骤操作:

  1. 注册IActionContextAccessor

    public void ConfigureServices(IServiceCollection services)
    {
    
        services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
    
        //rest services
    }
    
  2. MyRequiredIfNotAttribute

    public class MyRequiredIfNotAttribute : RequiredAttribute//ValidationAttribute
    {
        private Type _type;
        public MyRequiredIfNotAttribute(Type type) {
            _type = type;
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var actionContext = validationContext.GetRequiredService<IActionContextAccessor>();
            var controllerActionDescriptor = actionContext.ActionContext.ActionDescriptor as ControllerActionDescriptor;
            var controllerTypeName = controllerActionDescriptor.ControllerTypeInfo.FullName;
            if (_type.FullName == controllerTypeName)
            {
                return ValidationResult.Success;
            }
            else
            {
                return base.IsValid(value, validationContext);
            }            
        }
    }
    
  3. 用法

    public class MyModel
    {
        [MyRequiredIfNot(typeof(MyController))]
        public string Name { get; set; }
    }