1

How do I pass a view model and another parameter to my action method using jquery ajax?

with what I'm doing now, the action method is not being called. I think the cause is probably because the parameters are not being passed correctly in the data object of the jquery ajax call:

jQuery ajax:

$('#form-login').submit(function (event) {
                event.preventDefault();

                $.ajax({
                    url: "/Account/LogOn/",
                    data: $('#form-login').serialize(),
                    contentType: 'application/json; charset=utf-8',
                    success: function (data) {
                        if (data.userAuthenticated) {
                            window.location.href = data.url;
                        } else {
                            formBlock.clearMessages();
                            displayError($('#errorcred').val());
                        }
                    },
                    error: function () {
                        formBlock.clearMessages();
                        displayError($('#errorserver').val());
                    }
                });
        });

Action method (which accepts the view model and another parameter):

[HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {
        // Validate the email and password
        if (ModelState.IsValid)
        {
            if (MembershipService.ValidateUser(model.UserName, model.Password))
            {
                FormsService.SignIn(model.UserName, model.RememberMe);
                if (Url.IsLocalUrl(returnUrl))
                {
                    if (Request.IsAjaxRequest())
                    {
                        return Json(new { userAuthenticated = true, url = returnUrl, isRedirect = true });
                    }
                    else
                    {
                        return Redirect(returnUrl);
                    }
                }
                else
                {
                    if (Request.IsAjaxRequest())
                    {
                        return Json(new { userAuthenticated = true, url = Url.Action("Index", "Home"), isRedirect = true });
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
            } 
        }
        else
        {
            if (Request.IsAjaxRequest())
            {
                return Json(new { userAuthenticated = false, url = Url.Action("LogOn", "Account") });
            }
            else
            {
                ModelState.AddModelError("", adm.ErrorUserNamePassword);
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }
vobs
  • 133
  • 1
  • 5
  • 16

2 Answers2

0

Remove the following from the $.ajax call:

contentType: 'application/json; charset=utf-8',

You have specified application/json encoding but the $('#form-login').serialize() function is sending application/x-www-form-urlencoded content.

As far as sending the returnUrl parameter is concerned, you could simply read it from the form action where it should be present (if you used the Html.BeginForm() helper):

$.ajax({
    url: this.action,
    ...
});

Also you probably want to rename the event variable with something else as this is a reserved word in javascript:

$('#form-login').submit(function (e) {
    e.preventDefault();

    ...
});
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • But how do the parameters get mapped correctly with $('#form-login').serialize() since I have two parameters for the action method ? – vobs Jul 07 '13 at 14:37
  • The `$('#form-login').serialize()` will only take the parameters that are present as `input` fields in the form. I noticed that you have a `returnUrl` parameter. This parameter is normally present in the query string when the Forms Authentication module redirected to the Login page. And if you used the `@Html.BeginForm()` helper in it, it will be part of the `action` attribute of the form. So when you use `url: this.action` instead of hardcoding it as you did (`url: "/Account/LogOn/"`) it will get passed to the action. – Darin Dimitrov Jul 07 '13 at 14:39
  • If you wanted to pass manually an additional parameter, the easiest would be to include a hidden field in your form and then set the value of this hidden field in your javascript code before calling the $.ajax method. Then the .serialize function will take it into account. – Darin Dimitrov Jul 07 '13 at 14:40
0

The only way I have found to do this is to just include the second parameter in your viewmodel and continue to serialize your form the way you are doing now.

pforsthoff
  • 474
  • 1
  • 3
  • 15