Avoiding Duplicate form submission in Asp.net MVC

2020-05-16 01:55发布

问题:

I am rendering a form in Asp.net MVC with a submit button. The page redirects after successful record addition into the database. Following is the code :-

[HttpPost]
public ActionResult Create(BrandPicView brandPic)
{
    if (ModelState.IsValid)
    {
        if (!String.IsNullOrEmpty(brandPic.Picture.PictureUrl))
        {
            Picture picture = new Picture();
            picture.PictureUrl = brandPic.Picture.PictureUrl;
            db.Pictures.Add(picture);
            brandPic.Brand.PictureId = picture.Id;
        }
        db.Brands.Add(brandPic.Brand);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View();
}

But, while testing, I saw that if the form is clicked again and again, the multiple entries are submitted and saved into the database.

How can i make sure that if the form has been submitted once to the server, then no duplicates are submitted.

回答1:

I don't think this is quite a duplicate of the answer referenced in the comment, since the link is for spring MVC, and this question is for .NET MVC.

I actually spent a few hours on this a while back, and came up with the following. This javascript hooks nicely with the unobtrusive jquery validation, and you can apply it to any form that has <input type="submit". Note that it uses jquery 1.7's on function:

$(document).on('invalid-form.validate', 'form', function () {
    var button = $(this).find('input[type="submit"]');
    setTimeout(function () {
        button.removeAttr('disabled');
    }, 1);
});
$(document).on('submit', 'form', function () {
    var button = $(this).find('input[type="submit"]');
    setTimeout(function () {
        button.attr('disabled', 'disabled');
    }, 0);
});

The setTimeouts are needed. Otherwise, you could end up with a button that is disabled after clicked even when client-side validation fails. We have this in a global javascript file so that it is automatically applied to all of our forms.



回答2:

Disable the button on Submit clicked. This can be done using JQuery/Java Script.

Look at this example on how to do this.



回答3:

The solution for mvc applications with mvc client side validation should be:

$('form').submit(function () {
    if ($(this).valid()) {
        $(':submit', this).attr('disabled', 'disabled');
    }
});


回答4:

You can use ajax.BeginForm insted of html.BeginForm to achieve this, if you use OnSuccess insted of OnBegin you can be sure that your method execute successful and after that your button turn to deactivate,with ajax you stay in current view and you can update your current view instead of redirection

@using (Ajax.BeginForm(
new AjaxOptions
{
    HttpMethod = "post",
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "dive",
    OnBegin="deactive"
}))
{
//body of your form same as Html.BeginForm
<input type="submit" id="Submit" value="Submit" />
}

and use this jquery in your form:

<script type="text/javascript" language="javascript"> function deactive() { $("#Submit").attr("disabled", true); }</script>

be careful for using ajax you have to call this scrip in the end of your page

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>


回答5:

You can use this one. It includes unobtrusive jQuery validation.

$(document).on('submit', 'form', function () {
    var buttons = $(this).find('[type="submit"]');
    if ($(this).valid()) {
        buttons.each(function (btn) {
            $(buttons[btn]).prop('disabled', true);
        });
    } else {
        buttons.each(function (btn) {
            $(buttons[btn]).prop('disabled', false);
        });
    } });

For jQuery validation please incllude

~/Scripts/jquery.validate.min.js
~/Scripts/jquery.validate.unobtrusive.min.js


回答6:

Disabling the button is fine via JavaScript but what if the user has it disabled or they bypass it? If you use client side security then back it up with server side. I would use the PRG pattern here.