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) });">
Html. BeginForm() will create a form on the page that submits its values to the server as a synchronous HTTP request, refreshing the entire page in the process. Ajax. BeginForm() creates a form that submits its values using an asynchronous ajax request.
Ajax. BeginForm is the extension method of the ASP.NET MVC Ajax helper class, which is used to submit form data to the server without whole page postback. To work Ajax. BeginForm functionality properly, we need to add the reference of jquery.
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"
?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With