JQuery and Ajax.BeginForm() posting same data twice

Go To StackoverFlow.com

12

Ok I'm a total web newbie but I must admit I'm totally hooked now. Here's my problem:

I have a page with an MVCContrib grid and a "Add Accounts" link that brings up an Ajax form wrapped in a JQuery dialog. When I go through the workflow the first time everything works great. I can add a new item and refresh the grid all via JQuery / Ajax (so I think). However, when I try to add the form a second time, the data from the first form is always submitted. I've been looking at the problem for way too long and must admit I'm totally stuck. Btw - I'm sure I'm doing this totally wrong so feel free to suggest anything better.

Here's the form:

@using (Ajax.BeginForm("SaveCheckAccount", "UserManagement", null, new AjaxOptions { OnSuccess = "onAccountAdded", OnFailure = "onAccountAddedFailed"}, new { id = "accountDetails" }))
{
    @Html.ValidationSummary(true)
    @Html.HiddenFor(model => model.Id)
    @Html.HiddenFor(model => model.version)
    @Html.HiddenFor(model => model.User_Id)
    @Html.HiddenFor(model => model.IsDefault)        
    <table>
        <tr>
            <td>
                Account Number
            </td>
            <td>
                @Html.TextBoxFor(model => model.AccountNumber)
                @Html.ValidationMessageFor(model => model.AccountNumber, "*")
            </td>
        </tr>
        <tr>
            <td>
                Routing Number
            </td>
            <td>
                @Html.TextBoxFor(model => model.RoutingNumber)
                @Html.ValidationMessageFor(model => model.RoutingNumber, "*")
            </td>
        </tr>
        <tr>
            <td>
                Account Type
            </td>
            <td>
                @Html.DropDownListFor(model => model.AccountType_Id, new SelectList(@accountTypes, "ID", "Name", Model.AccountType_Id))
                @Html.ValidationMessageFor(model => model.CheckAccountType)
                @Html.ValidationMessageFor(model => model.AccountType_Id, "*")
            </td>
        </tr>
        <tr>
            <td>
                Bank Name
            </td>
            <td>
                @Html.TextBoxFor(model => model.BankName)
                @Html.ValidationMessageFor(model => model.BankName, "*")
            </td>
        </tr>
        <tr>
            <td>
                Account Name
            </td>
            <td>
                @Html.TextBoxFor(model => model.AccountName)
                @Html.ValidationMessageFor(model => model.AccountName, "*")
            </td>
        </tr>
    </table>   
}

<script type="text/javascript">
    $.ajaxSetup({ cache: false });
</script>

This javascript resides in bank.js file

function BindCommands(createUrl) {

      $("#modalAdd").live("click", function (e) {
          var dialogBox = $("<div>");
          e.preventDefault();
          $(dialogBox).dialog({
              autoOpen: false,
              resizable: false,
              title: 'Create Account',
              modal: true,
              show: { effect: "blind", duration: 50 },
              hide: { effect: "blind", duration: 50 },
              open: function (event, ui) {
                  $.ajax(
                      {
                          type: "Get",                          
                          url: createUrl,
                          success: function (result) {
                              $(dialogBox).html(result);
                          }
                      });
              },

              buttons: {
                  Save: function () {
                      $("#accountDetails").submit();
                      $(this).dialog('close');                      
                  },
                  Cancel: function () {
                      $(this).dialog("close");
                  }
              }
          });
          $(dialogBox).dialog('open');
      });
  }

  function onAccountAdded(data, status, xhr) {      
      $("#accounts-grid").html(data);
  };

  function onAccountAddedFailed(data, status, xhr) {
      alert("Failed");      
  };

The for is intially rendered by clicking the add link on this view:

<script type="text/javascript">
    $.ajaxSetup({cache:false});
    $(document).ready(function() {
        var createUrl = '@Url.Action("NewBankAccountDetails", "UserManagement", new {userId=@Model.Id})';
        BindCommands(createUrl);
    });

</script>       
@if (Model != null && Model.Id > 0)
{

    <tr>
        <td class="header" colspan="2">
            User Accounts
        </td>
    </tr>
    <tr>
        <td>
            <a href="#" id="modalAdd">Add Account</a>
        </td>
    </tr>

    Html.RenderPartial("_BankAccountGrid", Model.CheckAccounts);
}
2012-04-04 19:30
by dalcantara


40

I have had the same issue and banged my head against a wall until I noticed the following script being included twice:

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

I had it script set inside my bundle and the view templates also included it which resulted in double post's by the ajax form.

Hope it helps, if not double the bounty:-P

2013-01-18 10:16
by Ben Pretorius
I honestly hoped this was my issue (as in the debugger I can see two of every file for some reaso) but its not - Worthy7 2016-09-01 07:41
Thx for saving my day - Pilgerstorfer Franz 2016-12-28 16:24
This Answer has to be marked as correct one - AlphaTry 2017-07-12 11:14
It would be nice if the OP accepts the answer :- - Ben Pretorius 2017-07-17 08:26


0

I had this same problem today. Ben's answer provided a clue for me, but my problem wasn't as obvious as seeing jquery.unobtrusive-ajax.js twice in the html source. I was converting several standard views to partial views, so I had methods with a return type of ActionResult that were using the View method to return a type of ViewResult:

public ActionResult CreateView()
{
    var model = new CreateViewModel();
    return View("Create", model);
}

In my process of converting to partial views, I made a new .cshtml view file called _Create.cshtml and modified the controller method to:

public ActionResult CreateView()
{
    var model = new CreateViewModel();
    return View("_Create", model);
}

At this point I was experiencing the double posting from an ajax form in the _Create partial view. The solution was to use the PartialView method to return a type of PartialViewResult:

public ActionResult CreateView()
{
    var model = new CreateViewModel();
    return PartialView("_Create", model);
}

It was hard to spot because everything was working fine besides the double-posting of ajax forms, since both ViewResult and PartialViewResult are valid types of ActionResults.

2018-11-05 21:40
by AnalogWeapon


0

I know this is a very old question but I came across this same problem today. I'm adding the solution I found now just in case someone else comes across this. If you are opening a dialog or page that creates the form then when you close that form (which is what I think the OP is doing) then the events tied to that form don't actually get removed. If you are using jQuery then I found that if you call $('#form').remove() before you actually remove the form from the DOM then those events are removed and you won't get multiple calls to the action. Hope this helps.

2018-11-23 21:07
by wadek
Ads