从验证属性调用指定的操作



我目前正在创建一个类似于现有"Remote"属性的属性。客户端验证是通过javascipt调用一个操作来检查(针对我们的数据库)输入是否有效来进行的。问题是,当涉及到服务器端验证时,我无法确定如何调用该操作。"远程"属性没有帮助,因为"不进行服务器端验证"

没有显示客户端代码,因为它运行良好。

属性

[AttributeUsage(AttributeTargets.Property)]
public class AjaxValidation : Attribute, IModelValidator {
    private readonly string _action;
    private readonly string _area;
    private readonly string _controller;
    public AjaxValidation(string action, string controller = null, string area = null) {
        _action = action;
        _area = area;
        _controller = controller;
    }
    public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context) {
        List<ModelValidationResult> result = new List<ModelValidationResult>();
        //Need to call the action and check the result here
        //Create the controller with reflection?
        //Call the method with reflection?
        if(false was returned) {
            result.Add(new ModelValidationResult("", "{0} is invalid"));
        }
        return result;
    }
}

显示其使用的模型

[AjaxValidation ("Validate", "Home", "Examples")]
public string Value{ get; set; }

以及模型将调用的动作(客户端也使用)

public ActionResult Validate(string id) {
    if (id.Length == 3) {
        return Json(new { Success = true });
    } else {
        return Json(new { Success = false });
    }
}

您在这里混合了各种概念,这让您自己很难理解。

相反,您应该将验证逻辑提取到一个单独的服务中,而不是在控制器中捕获验证逻辑,您可以在控制器和属性中轻松使用该服务。有很多方法可以使用各种内置的DataAnnotations等来实现这一点,但至少可以将代码拉到不同的服务中。

首先,创建您的验证服务

public class Validator
{
  public bool Validate(string id)
  {
    if (id.Length == 3) {
        return true;
    } else {
        return false;
    }
  }
}

将此注入到现有的控制器中,以根据需要返回结果:

public class ValidationController
{
  private readonly ValidationService _validator;
  public ActionResult Validate(string id) {
    var result = _validator.Validate(id);
    return Json(new { Success = result });
  }
}

然后,您需要配置您的操作过滤器,以便类似地注入验证器。我建议你阅读ASP。NET核心操作筛选器,以及如何在运行时使用ServiceFilter属性注入服务。这个答案描述了如何实现我认为你正在寻找的目标。

相关内容

  • 没有找到相关文章

最新更新