2012-01-06 9 views
19

Renderuję formularz w Asp.net MVC za pomocą przycisku przesyłania. Strona przekierowuje po pomyślnym dodaniu rekordu do bazy danych. Poniżej znajduje się kod: -Unikanie zduplikowanego przesyłania formularzy w Asp.net MVC przez dwukrotne kliknięcie przesłać

[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(); 
} 

Ale podczas testów, widziałem, że jeśli formularz jest znowu i znowu kliknięciu wielokrotne wpisy są przekazywane i zapisywane w bazie danych.

W jaki sposób mogę się upewnić, że jeśli formularz został przesłany jeden raz na serwer, nie zostaną przesłane żadne duplikaty.

+1

To już został poproszony kilka razy wcześniej: http://stackoverflow.com/questions/2324931/duplicate-form-submission-in-spring – Kane

+0

@Kane , +1 i przepraszam. Zawsze sprawdzam, czy pytanie zostało zadane wcześniej, ale być może nadszedł czas na zmianę liczby okularów ;-) ..... –

+0

Możliwy duplikat [Jak zapobiec wielokrotnemu przesyłaniu formularzy w .NET MVC bez używania Javascript?] (https://stackoverflow.com/questions/4250604/how-do-i-prevent-multiple-form-submission-in-net-mvc-without-using-javascript) – KyleMit

Odpowiedz

61

Nie sądzę, że jest to dość duplikat odpowiedzi, do której odnosi się komentarz, ponieważ link dotyczy wiosennego MVC, a to pytanie dotyczy .NET MVC.

Właściwie to spędziłem kilka godzin, a potem wymyśliłem następujące. Ten javascript ładnie się haczy z dyskretną walidacją jquery i można go zastosować do dowolnej formy, która ma <input type="submit". Zauważ, że wykorzystuje funkcję jQuery on 1,7 za: Potrzebne są

$(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); 
}); 

W setTimeouts. W przeciwnym razie może się zdarzyć, że przycisk zostanie wyłączony po kliknięciu, nawet po niepowodzeniu sprawdzania poprawności po stronie klienta. Mamy to w globalnym pliku javascript, dzięki czemu jest on automatycznie stosowany do wszystkich naszych formularzy.

+0

Zanim to wypróbuję, chcę poinformuję, że moja aplikacja używa jquery-1.5.1 dodanej przez VS na początku. Zastąpienie wersji 1.7 skutkuje moją aplikacją? –

+0

Nie mogę powiedzieć, ale nie powinienem. Jeśli chcesz pozostać przy 1.5, możesz po prostu zmienić 'on' na' live'. – danludwig

+6

To dobrze, ale należy wspomnieć, że można użyć przycisków, których nie znalazłoby.Jeśli używasz obu wejść i przycisków, musisz przeszukiwać zarówno jak, przycisk var = $ (this) .find ('input [type = "submit"], button [type = "submit"]'); – erosebe

6

Wyłącz przycisk "Wyślij". Można to zrobić za pomocą JQuery/Java Script.

Zobacz, jak to zrobić: this example.

0

Wyłączenie przycisku jest w porządku za pomocą JavaScript, ale co jeśli użytkownik go wyłączył lub pomija go? Jeśli korzystasz z zabezpieczeń po stronie klienta, wykonaj kopię zapasową po stronie serwera. Chciałbym użyć tutaj PRG pattern.

+0

Z linku, do którego się odwołałeś - wzorzec PRG nie może uwzględnić każdego scenariusza duplikowania formularza. Niektóre znane zduplikowane formularze, których PRG nie może rozwiązać, są następujące: ... jeśli użytkownik sieci kliknie przycisk przesyłania kilka razy przed załadowaniem odpowiedzi serwera (można temu zapobiec, używając JavaScript, aby wyłączyć przycisk po pierwszym kliknięciu). – danludwig

+0

@olivehour poprawne, jestem głupi i nie przeczytałem poprawnie pytania. – eth0

+2

@ eth0 - nie, ty * właśnie * nie odczytałeś poprawnie pytania –

0

Można używać Ajax.BeginForm insted html.BeginForm aby to osiągnąć, jeśli używasz OnSuccess insted OnBegin można mieć pewność, że metoda wykonać udany, a potem swoją kolej, aby wyłączyć przycisk, z ajax pobyt w bieżący widok i można wykonać aktualizację widoku zamiast przekierowania

@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" /> 
} 

i używać tego jQuery w formularzu:

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

uważać za korzystanie ajax masz do c Wszystko to taistry w końcu swojej stronie

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> 
Powiązane problemy