36

Context: Asp.Net MVC3 w/Razor

I am trying to put a login form on a Razor layout (formerly master page) so that, when the user times out, s/he can be prompted to login without being redirected (as in RallyDev). So, I have created a partial _LogOn.cshtml with all the requisite stuff (username, etc.) inside an Ajax.BeginForm with an UpdateTargetId that points to a div that holds the logon controls inside the ajax form. The form posts back to the AccountsController.RefreshLogOn action, but obviously, the containing page may have been rendered from a different controller. The RefreshLogOn action returns PartialView("_LogOn"). In any case, my expectation/desire is that only the controls inside this div are replaced. What is happening instead is that my page location changes to /Accounts/RefreshLogon and the whole page is replaced by the partial. Is there another approach I should be taking?

Here's the relevant code:

_LogOn.cshtml

 @{
        using (Ajax.BeginForm("RefreshLogOn", "Accounts", 
            new AjaxOptions { 
                      OnSuccess = "logonSucceeded", 
                      OnFailure = "logonFailed",         
                      HttpMethod = "Post", 
                      UpdateTargetId = "user-info" }, 
            new { @id = "refresh"}))
        {  
        @Html.AntiForgeryToken()

       <div id="user-info">
                <p>Your session has expired.</p>
            <div class="error">@Html.ValidationSummary()</div>
            <table>
                <tr>
                    <td>Username:</td>
                    <td>@Html.TextBoxFor(model => model.UserName)</td>
                </tr>
                <tr>
                    <td>Password:</td>
                    <td>@Html.PasswordFor(model => model.Password)</td>
                </tr>
                <tr>
                    <td>Remember Me:</td>
                    <td>@Html.CheckBoxFor(model => model.RememberMe)</td>
                </tr>

            </table>
        </div>
            }
        }

AccountsController

public ActionResult RefreshLogOn (LogOnModel model)
{
    if (ModelState.IsValid)
    {
        if (MembershipService.ValidateUser(model.UserName, model.Password))
        {
            ...content elided...

            return PartialView("_LogOn");
        }

        ModelState.AddModelError("", ErrorMessages.IncorrectUsernameOrPassword);
    }

    return PartialView("_LogOn", model);
}

Ajax.BeginForm --> form tag generated:

<form action="/Accounts/RefreshLogOn" id="refresh" method="post" 
    onclick="Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));"
    onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), 
    { 
    insertionMode: Sys.Mvc.InsertionMode.replace, 
    httpMethod: &#39;Post&#39;, 
    updateTargetId: &#39;user-info&#39;, 
    onFailure: Function.createDelegate(this, logonFailed), 
    onSuccess: Function.createDelegate(this, logonSucceeded) 
    });">
sydneyos
  • 4,527
  • 6
  • 36
  • 53

6 Answers6

40

Ajax.* helpers in ASP.NET MVC 3 use unobtrusive jquery so make sure that you have referenced the jquery.unobtrusive-ajax.js script in your view. Also you could use FireBug to see what's happening under the scenes and why the form doesn't send an AJAX request.

Also the UpdateTargetId = "form" seems suspicious especially when your form has the refresh id: @id = "refresh". Is there some other element inside your DOM with id="form"? Maybe you meant UpdateTargetId = "refresh"?

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Yeah - I know that's a little confusing - my ajax form has the id = "refresh" and my update target, inside the ajax form, has the id = "form" - was going to change that anyway, just in case the word "form" was confusing anything. But I'm hoping the unobtrusive-ajax tip is the key. Will report back shortly - thanks! – sydneyos Feb 10 '11 at 18:55
  • Sadly, no joy. What I am seeing is that the form tag generated by the Ajax helper is targeting the MicrosoftAjax libraries, not unobtrusive javascript. I am updating the post to show the generated form tag. The Helpers I have are in System.Web.Mvc.dll v4.0.30319. Should I have something else? – sydneyos Feb 10 '11 at 19:16
  • 1
    @sydneyos, if you think that the Ajax helper is using MicsoroftAjax then you need to include those libraries. And let me give you an advice: get rid of this crap and use jquery. – Darin Dimitrov Feb 10 '11 at 19:21
  • Also note, I have UnobtrusiveJavaScriptEnabled = false in my web.config as my form validation in another page started to fail with that set to true. But I did have those libraries (Microsoftxxx) already referenced. – sydneyos Feb 10 '11 at 19:22
  • Thank you so much, was trying hard what was going wrong, and Firebug helped and here is my [answer](http://stackoverflow.com/a/30213504/2218697). – Shaiju T May 13 '15 at 11:30
6

Note: my problem was first, i referenced wrong ajax script file jquery.validate.unobtrusive.min.js instead of jquery.unobtrusive-ajax.js and latest jquery version doesn't worked, only jquery-1.7.1.min.js worked for me.

i was trying to return content after successful entry

so here is the order:

<script src="~/js/jquery-1.7.1.min.js"></script>
<script src="~/js/jquery.validate.min.js"></script>
<script src="~/js/jquery.unobtrusive-ajax.min.js"></script>

Post of Darin and Richard Everett helped. hope helps.

Community
  • 1
  • 1
Shaiju T
  • 6,201
  • 20
  • 104
  • 196
3

I had the same problem and solution was:

  • Check that UnobtrusiveJavaScriptEnabled is true.
  • Add reference to jquery.unobtrusive-ajax.js as Darin adviced.

Unfortunatelly, it will not help for you because you set UnobtrusiveJavaScriptEnabled to false, but can help for somebody.

Ivan Sokalskiy
  • 812
  • 7
  • 14
  • I have been working on an MVC4 project where my ajax form used to submit via ajax and then suddenly didn't. I tried all the advice and then finally found your point to set UnobtrusiveJavaScriptEnabled to true. This did the trick. Thanks so much Ivan Sokalskiy. – Ozzy Jan 16 '14 at 16:56
1

Notice if you use Asp.Net template like I do, It bundles the file to bundles/jqueryval. So you have to add

@Scripts.Render("~/bundles/jqueryval")

to the page.

Ronen Festinger
  • 2,260
  • 1
  • 23
  • 32
1

Late but correct. Make sure to reference the unobtrusive-ajax.js file as well as the MicrosoftAjax.js and MicrosoftMvcAjax.js files in that order. Works

dis.iz.peez
  • 89
  • 1
  • 9
1

Besides checking if the .js is referenced, also check if no other form tags are being rendered. In my case, I had another form tag on the master page with the default action that was causing the whole page to reload.

bubbassauro
  • 3,969
  • 2
  • 45
  • 45