I have a login form that is shown on all pages of my mvc site asking the user to login or shows them a welcome message if they are already logged in along with various account details (company logo etc), I do not have a login page itself all login is handled via this 'widget'
To implement this I have the following so far
In my main layout
<div id="top_right">
@{ Html.Partial("_LogOnPartial");}
</div>
_LogOnPartial.cshtml
@if (Request.IsAuthenticated)
{
// TODO: show company logo
Html.RenderAction("Details", "Account");
}
else
{
Html.RenderAction("LogOn", "Account");
}
Account controller
public class AccountController : Controller
{
public PartialViewResult LogOn()
{
return PartialView();
}
[HttpPost]
public ActionResult LogOn(LogOnModel userDetails, string returnUrl)
{
//TODO: validate user here
if(ModelState.IsValid)
{
if(Membership.ValidateUser(userDetails.UserName, userDetails.Password))
{
FormsAuthentication.SetAuthCookie(userDetails.UserName, userDetails.RememberMe);
return Redirect(returnUrl);
}
else
{
ModelState.AddModelError("", "The username or password provided was incorrect");
}
}
return PartialView(userDetails);
}
public PartialViewResult Details()
{
//TODO: query membership for user information
var user = new UserDetailsViewModel();
return PartialView(user);
}
}
}
LogOn.cshtml
@model LogOnModel
<div id="login">
@Html.ValidationSummary()
<h2>Start by Loggin in</h2>
@using (Html.BeginForm("LogOn", "Account"))
{
@Html.Hidden("returnUrl", Request.Url.PathAndQuery)
<table width="100%" border="0" cellspacing="0" cellpadding="5">
<tr>
<td>
<span class="bluey">Username:</span><br />
@Html.TextBoxFor(m => m.UserName,new {tabindex="1", Class = "field"})
@Html.ValidationMessageFor(m => m.UserName, "*")
</td>
<td>
<span class="bluey">Password:</span><br />
@Html.TextBoxFor(m => m.Password, new {tabindex = "2", Class="field"})
@Html.ValidationMessageFor(m=> m.Password, "*")
</td>
</tr>
<tr>
<td>
<input name="login" type="submit" value="Submit" class="input_btn" tabindex="3" />
</td>
<td>@Html.CheckBoxFor(m=>m.RememberMe) @Html.LabelFor(m=> m.RememberMe) <span class="bluey"> | </span> @Html.ActionLink("Forgot Password?", "Password", "User")></td>
</tr>
</table>
}
</div>
I've read a few posts and it would appear I will need to change my LogOn.cshtml to use jquery to do a post do the /Account/LogOn action method and then update the the html of the div success or failure.
I've seen it done with a custom RenderPartialViewToString but someone also recommended that returning the Partial from the Action was enough and this would be processed correctly via the jquery code, replacing the div (or whatever element) with the new html.
I also saw an example returning Json(model) but I'm not sure if that would return the actual view or just the model data encoded as json
Are both of these approaches viable or is there a better way to do this?