Reputation: 4557
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: 'Post',
updateTargetId: 'user-info',
onFailure: Function.createDelegate(this, logonFailed),
onSuccess: Function.createDelegate(this, logonSucceeded)
});">
Upvotes: 36
Views: 31526
Reputation: 6609
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.
Upvotes: 6
Reputation: 2405
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.
Upvotes: 1
Reputation: 4279
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.
Upvotes: 1
Reputation: 89
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
Upvotes: 1
Reputation: 812
I had the same problem and solution was:
Unfortunatelly, it will not help for you because you set UnobtrusiveJavaScriptEnabled to false, but can help for somebody.
Upvotes: 3
Reputation: 1038820
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"
?
Upvotes: 40