FluentValidation谓词验证程序不起作用

时间:2014-07-01 13:18:53

标签: c# jquery ajax asp.net-mvc-5 fluentvalidation

我有模特课:

[FluentValidation.Attributes.Validator(typeof(CrcValidator))]
public class CrcModel
{
    [Display(Name = "Binary value")]
    public string binaryValue { get; set; }

    [Display(Name = "Generator")]
    public string generator { get; set; }
}

带谓词的验证器类:

public class CrcValidator : AbstractValidator<CrcModel>
{
    public CrcValidator()
    {
        RuleFor(x => x.binaryValue)
            .NotEmpty().WithMessage("Binary value is required")
            .Matches(@"(0|1)*").WithMessage("This value is not valid binary value");

        RuleFor(x => x.generator)
            .NotEmpty().WithMessage("Generator is required")
            .Matches(@"(0|1)*").WithMessage("Generator must be valid binary value")
            .Must(CompareLength).WithMessage("Length must be lesser than length of binary value - 1");
    }

    private bool CompareLength(CrcModel model, string value)
    {
        return model.binaryValue.Length - 1 > model.generator.Length;
    }
}

我在CompareLength函数中放置了断点,并且从表单中正确读取了每个值。问题是即使我的谓词函数返回false,我的表单也会通过验证。 NotEmpty和Matches规则工作得非常好只是似乎必须被忽略。

修改

jQuery for submit按钮(类型为“button”):

$(function () {
$("#Button1").click(function () {
    var form = $("#Form1");
    if ($(form).valid()) {
        $.ajax({
            type: 'POST',
            url: 'Compute',
            data: $(form).serialize(),
            success: function (result) {
                $("#remainder").val(result.remainder);
                $("#signal").val(result.signal);
            }
        });
    }
}); 
});

控制器动作处理表单提交:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Compute([Bind(Include = "binaryValue,generator")] CrcModel model)
    {
        if (ModelState.IsValid)
        {
            model.remainder = ComputeFrame(model.binaryValue, model.generator);
            model.signal = model.binaryValue + model.remainder;
        }

        return Json(new { remainder = model.remainder, signal = model.signal });
    }

来自Must规则的验证适用于服务器端但消息未显示。

1 个答案:

答案 0 :(得分:1)

编辑:在几条评论之后,FluentValidation中对Must的所有调用中定义的验证仅在服务器上执行。没有相当于任意C#代码的JavaScript。 C#中的FluentValidation规则由MVC框架转换为HTML中表单字段标记上的各种HTML5 data-*属性,jQuery Validate在客户端验证期间读取。由于无法将谓词(委托方法)中定义的验证规则转换为HTML5 data-*属性,因此这些验证规则仅可强制执行服务器端。

编辑#2:看到Must验证是由AJAX调用触发的,您需要做几件事:

  1. 将HTTP状态代码设置为非200响应,以触发jQuery中的错误处理机制。另外,将HTTP状态设置为422(Unprocessable Entity)

    HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Compute([Bind(Include = "binaryValue,generator")] CrcModel model)
    {
        if (ModelState.IsValid)
        {
            model.remainder = ComputeFrame(model.binaryValue, model.generator);
            model.signal = model.binaryValue + model.remainder;
    
            return Json(new { remainder = model.remainder, signal = model.signal });
        }
        else
        {
            Response.StatusCode = 422;
    
            return Json(new { errors = ModelState.Errors });
        }
    }
    
  2. 更改jQuery.ajax调用:

    $(function () {
        $("#Button1").click(function () {
            var form = $("#Form1");
            if ($(form).valid()) {
                $.ajax({
                    type: 'POST',
                    url: 'Compute',
                    data: $(form).serialize(),
                    success: function (result) {
                        $("#remainder").val(result.remainder);
                        $("#signal").val(result.signal);
                    },
                    error: function(xhr) {
                        if (xhr.status == 422) {
                            var errors = JSON.parse(xhr.responseText);
    
                            console.log(errors);
                        }
                    }
                });
            }
        }); 
    });
    
  3. 另一种方法是只渲染一个将一个或多个错误消息显示为HTML的Partial,然后在DIV中设置该HTML并显示DIV标记。