MVC 3指定远程验证的验证触发器

时间:2011-01-25 21:10:13

标签: validation asp.net-mvc-3 unobtrusive-validation

我使用MVC 3不引人注目的验证实现了远程验证,如下所示

模型

public class MyViewModel {
    [Remote("ValidateAction", "Validation")]
    public string Text { get; set; }
}

控制器

public partial class ValidationController : Controller
{
    public virtual JsonResult ValidationAction(string aTextToValidate)
    {
        if(aTextToValidate == /* some condition */)
            return Json(true, JsonRequestBehavior.AllowGet);
        return Json("This is not valid, Try Again !", JsonRequestBehavior.AllowGet);
    }
}

视图

@using (Html.BeginForm() {
    @Html.TextBoxFor(m => m.Text)
    @Html.ValidationMessageFor(m => m.Text)
}

就是这样,一切正常,但ValidationAction会在每次按键时触发,这是不理想的,我想在元素失去焦点时触发,但无法想象如何做到这一点

更新

实际上我已经注意到,默认情况下,验证会触发一次.l.e。第一次元素失去焦点,但是当试图纠正它时,验证然后触发onKeyUp。我认为这是预期的功能,并且考虑它可能非常有用。但是,知道是否可以修改此行为

会很有用

2 个答案:

答案 0 :(得分:5)

尝试

$.validator.setDefaults({ onkeyup: false });

它对我有用。

答案 1 :(得分:2)

虽然我认为没有针对此进行不显眼的验证(目的是验证每个按键的输入 - 用户友好),但这种方法有一种解决方法:
您可以将这些极少数行(标记为//this is my code)添加到jquery.validate.js并缩小它,或者您可以创建一个新的.js文件并添加以下代码。
请注意,如果您想要删除某些特定onkeyup的{​​{1}}(不是针对某些特定规则,即远程),有一种特定且简单的方法可以在jquery站点中找到它。
此代码仅会忽略input事件的remote规则,并会在keyuprequired事件中验证其他人(即keyup)。

focuseout

<强>更新
上面的代码肯定是有效的,但我想注意到我试图通过不带整个函数来使代码更整洁,即:

(function ($) {
 jQuery.validator.setDefaults({
    onkeyup: function (element) {
        $(element).data('firedON', 'keyup')    //this is my code
        if (element.name in this.submitted || element == this.lastElement) {
            this.element(element);
        }
    }
});

$.validator.methods.remote = function (value, element, param) {
    if ($(element).data('firedON') == 'keyup') {
       $(element).data('firedON') = '';
       return "dependency-mismatch";           //this 'if' is my code(thats it)
    }
    if (this.optional(element))
        return "dependency-mismatch";

    var previous = this.previousValue(element);
    if (!this.settings.messages[element.name])
        this.settings.messages[element.name] = {};
    previous.originalMessage = this.settings.messages[element.name].remote;
    this.settings.messages[element.name].remote = previous.message;

    param = typeof param == "string" && { url: param} || param;

    if (previous.old !== value) {
        previous.old = value;
        var validator = this;
        this.startRequest(element);
        var data = {};
        data[element.name] = value;
        $.ajax($.extend(true, {
            url: param,
            mode: "abort",
            port: "validate" + element.name,
            dataType: "json",
            data: data,
            success: function (response) {
                validator.settings.messages[element.name].remote = previous.originalMessage;
                var valid = response === true;
                if (valid) {
                    var submitted = validator.formSubmitted;
                    validator.prepareElement(element);
                    validator.formSubmitted = submitted;
                    validator.successList.push(element);
                    validator.showErrors();
                } else {
                    var errors = {};
                    var message = (previous.message = response || validator.defaultMessage(element, "remote"));
                    errors[element.name] = $.isFunction(message) ? message(value) : message;
                    validator.showErrors(errors);
                }
                previous.valid = valid;
                validator.stopRequest(element, valid);
            }
        }, param));
        return "pending";
    } else if (this.pending[element.name]) {
        return "pending";
    }
    return previous.valid;
}
} (jQuery));  

但它失败了,因为在将旧函数存储在本地var remote = $.validator.methods.remote; $.validator.methods.remote = function(a,b,c){ if ($(element).data('firedON') == 'keyup') return "dependency-mismatch"; return remote(a,b,c); } 变量中后,'remote'会引用其他地方,我无法修复this这段代码所以我带了上面的代码。