Before I ask the question let me just clarify that the objective of this exercise is research/proof of concept so answers about how the design could be improved or that there are easier ways to accomplish this, though appreciated, might not help to fulfill the objective.
I am modifying the template of an ASP .Net MVC 4 application so the log in functionality is implemented with an ajax request that only updates the partial view that contains the log in controls and leaves the rest of the page undisturbed.
So far what I've done is the following:
I've added a form on the partial view so that it can be posted and substituted the action link with a button
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { ReturnUrl = ViewBag.ReturnUrl }))
{
@Html.ValidationSummary(true)
if (Request.IsAuthenticated)
{
<p>
Hello, @Html.ActionLink(User.Identity.Name, "ChangePassword", "Account", routeValues: null, htmlAttributes: new {@class = "username", title = "Change password"})!
@Html.ActionLink("Log off", "LogOff", "Account")
</p>
}
else
{
<ul>
<li>@Html.LabelFor(m => m.UserName)</li>
<li>@Html.TextBoxFor(m => m.UserName)</li>
<li>@Html.LabelFor(m => m.Password)</li>
<li>@Html.PasswordFor(m => m.Password)</li>
<li><input class="loginLink loginButton" type="button" value="Log in"/></li>
<li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new {id = "registerLink"})</li>
</ul>
}
}
I modified the action like so
[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
ActionResult result = View("_LoginPartial", model);
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
result = Redirect(returnUrl);
}
else
{
result = View("_LoginPartial", model);
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
return result;
}
And I created this small Javascript file
var login = {
callLogin: function () {
var userName = $("#UserName").val();
var password = $("#Password").val();
var data = { UserName: userName, Password: password };
$("#login").load("/Account/Login", data);
}
};
$(document).ready(function () {
$(".loginButton").click(login.callLogin);
});
The log in per se works. The POST action method is being called and the credentials are validated. The problem is that the partial view is not being updated and I have to force a post back by going to another page so that I can see the partial as if the user is logged in.
What would be the missing ingredient to accomplish this?
Thank you.