Silent remote check ASP.NET MVC jQuery returns false positives

I will return to the project in which I worked 9 months ago, looking at some code that we wrote, and we hope that now there is a better way to do this ...

Although initially impressed by the unobtrusive validity of jQuery, we ended up having to build the hacked below (partially based on a blog post that I can't rely on right now) to deal with remote validation. The problem is that when the server-side verification process was slow - usually something related to calling the database - the validator did not wait for a response from the verification method and acted as if it had put a positive result.

The hack consists in basically continuing to check whether the validator has any pending requests and does not execute it until it receives it, when you can be sure of the true result of the check:

function SaveChangePassword() {

// Find form, fire validation
var $form = $("#btnSave").closest("form");

if ($form.valid()) {
//Do nothing - just firing validation
}

// Calls method every 30 milliseconds until remote validation is complete
var interval = setInterval(saveWhenValidationComplete, 30);

// Check if validation pending, save and clear interval if not
function saveWhenValidationComplete() {

    // Find form validator, check if validation pending - save once remote validation is finished
    var validator = $form.data("validator");
    if (validator.pendingRequest === 0) {

        clearInterval(interval);

        //Force validation to present to user (this will not retrigger remote validation)
        if ($form.valid()) {

            var closeButton = "<br/><input type='button' value='OK' style='font-size:small; font-weight:bold; float:right;' onclick=\"$('#changePasswordDialog').dialog('close');\" class='greenbutton' />";
            // If form is valid then submit
            $.ajax(
                {
                    type: "POST",
                    url: "/Account/SavePassword",
                    data: $form.serialize(),
                    success: function (result) {
                        var successMessage = "<div style='text-align:center; margin-top: 10px;'>" + result + "<div>";
                        $("#changePasswordDialog").html(successMessage + closeButton);
                            },
                    error: function (jqXhr, textStatus, errorThrown) {
                        // Populate dialog with error message and button
                        var errorMessage = "<div style='text-align:center'>Error '" + jqXhr.status + "' (Status: '" + textStatus + "', errorThrown: '" + errorThrown + "')<div>";
                        $("#changePasswordDialog").html(errorMessage + closeButton);
                    }
                });

        }

        // Else validation will show
    }

    // Else don't save yet, wait another 30 miliseconds while validation runs
};

// Prevent default and stop event propagation
return false;
}

I hope that some changes have occurred over the past 9 months, and this is no longer necessary! Any ideas are welcome, let me know if I can provide further information.

+4
source share
1 answer

, , (!) . javascript POST , , .

, ASP.NET MVC . :

public ActionResult SaveSomething(Something thing)
{
    if(!ModelState.IsValid)
    {
        return View("EditSomething", thing);
    }
    // otherwise, save something...
}

... , , , , , [Required] [StringLength(x)]. . [Remote] .

[Remote], :

public ActionResult CheckThingCodeValidity(string code)
{
    return Json(_thingCodeChecker.ThingCodeWorks(code), JsonRequestBehavior.AllowGet);
}

... - :

public ActionResult SaveSomething(Something thing)
{
    if(!_thingCodeChecker.ThingCodeWorks(thing.Code))
    {
        ModelState.AddModelError("Code", "This code is not valid.");
    }
    if(!ModelState.IsValid)
    {
        return View("EditSomething", thing);
    }
    // otherwise, save something...
}

, , , , , .

, , , . , , , , . - - , , , .

+2

Source: https://habr.com/ru/post/1536517/


All Articles