FluentValidation:在客户端获取CustomState

时间:2015-04-09 18:03:49

标签: jquery asp.net-mvc twitter-bootstrap fluentvalidation

我想将bootstraps .alert alert-warning类与FluentValidation集成以显示/隐藏警告消息。我以为我可以在规则上放置一个自定义状态并将其发送到客户端以显示和隐藏警报消息,但我无法弄明白。这是我到目前为止:

public class FooValidator : AbstractValidator<FooVm>
  {
    public FooValidator ()
    {
      RuleFor(model => model.Temperature)
        .NotNull()
        .LessThanOrEqualTo(model => model.MaxTemp)
          .WithState(model => ValidationType.Warning)
          .WithMessage("Warning, temp should be less than or equal to {ComparisonValue}")
        .GreaterThanOrEqualTo(model => model.MinTemp)
          .WithState(model => ValidationType.Warning)
          .WithMessage("Warning, temp should be greater than or equal to {ComparisonValue}");
    }
  }

这是我的LessThanOrEqualTo验证器来获取客户端规则。请注意我最后有一个TODO来设置客户端的状态参数

  public class LessThanOrEqualPropertyValidator : FluentValidationPropertyValidator
  {
    public LessThanOrEqualPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)
      : base(metadata, controllerContext, rule, validator)
    {
    }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
      if (!ShouldGenerateClientSideRules()) yield break;

      var validator = (LessThanOrEqualValidator)Validator;
      object val;
      string variableInMsg;

      var propertyToCompare = validator.MemberToCompare as PropertyInfo;

      // get the value from the property instead of using the property
      if (propertyToCompare != null)
      {
        val = this.Metadata.Container.GetType().GetProperty(propertyToCompare.Name).GetValue(this.Metadata.Container, null);
        variableInMsg = "ComparisonValue";
      }
      else
      {
        val = validator.ValueToCompare;
        variableInMsg = "ValueToCompare";
      }

      var errorMessage = new MessageFormatter()
          .AppendPropertyName(Rule.GetDisplayName())
          .AppendArgument(variableInMsg, val)
          .BuildMessage(validator.ErrorMessageSource.GetString());

      var rule = new ModelClientValidationRule();
      rule.ErrorMessage = errorMessage;
      rule.ValidationType = "lessthanorequal";
      rule.ValidationParameters["valuetocompare"] = val;
      rule.ValidationParameters["state"] = // TODO: how can i send state across, i know you can view it when validating the obj
      yield return rule;
    }
  }

这是我的客户端代码,我希望能够在params对象中获取状态。警告将始终返回true;

$.validator.addMethod("lessthanorequal", function (value, element, params) {
    var isValid = this.optional(element) || parseFloat(value) <= parseFloat(params.valuetocompare)

    // TODO: how to get state
    //if(params.state === "Warning") {
    //    if (isValid) {
    //        $(".alert-warning").hide();
    //    }
    //    else {
    //        $(".alert-warning").show();
    //    }
    //    return true;
    //}

    return isValid
});

$.validator.unobtrusive.adapters.add("lessthanorequal", ["valuetocompare"], function (options) {
    options.rules['lessthanorequal'] = options.params;
    if (options.message) {
        options.messages['lessthanorequal'] = options.message;
    }
});

1 个答案:

答案 0 :(得分:0)

感谢@KundanSinghChouhan指出我应该看到的东西。状态对象位于data-val属性中,但不是我可以直接在客户端上使用的值。以下是我在LessThanOrEqualPropertyValidator

中开展工作的方法
rule.ValidationParameters["state"] = this.CustomStateProvider.Invoke(null);

我不知道将ValidationError列表发回服务器时会产生什么影响,因为该类存储了State值,但如果我需要使用该值,我将会审核类。