I have a MasterModel class that basically handles a lot of data for partial views across shared layouts. However, when I try and return part of the object (or the entire MasterModel) in a form, such as "Login", no data is passed to the controller.
Here is part of the MasterModel:
public class MasterModel
{
public Login Login;
public Account Account;
public User User;
public MasterModel()
{
Login = new Login();
Account = new Account();
User = new User();
}
}
Here is part of the Login:
public class Login
{
public string Email {get;set;}
public string PasswordHash {get; private set;
public string FName {get;set;}
}
Here is part of the master Layout template that calls the partial view for a login:
@model Models.MasterModel
...
@{
Html.RenderPartial("../Partials/_Login", Model.Login);
}
...
And here is the _Login partial:
@model Models.Login
<div class="login-bar">
@if (Model != null && !string.IsNullOrWhiteSpace(Model.FName) )
{
var welcomeString = "Welcome back, " + Model.FName;
<p>@Html.ActionLink(welcomeString, "Overview", "Account")</p>
}
else
{
using (Html.BeginForm("Login", "Account", FormMethod.Post))
{
@Html.AntiForgeryToken()
<p>
@Html.Label("Email Address:")
@Html.EditorFor(login => login.Email, new { @class = "email" })
@Html.Label("Password:")
@Html.PasswordFor(login => login.PasswordHash)
<input type="submit" value="Login" class="button" />
@if (ViewBag.Message != null)
{
<shim class="red">@ViewBag.Message.ToString()</shim>
}
</p>
}
}
</div>
Here's the AccountController for the HttpPost for Login too:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(Login login, string returnUrl)
{
var master = new MasterModel();
// ModelState is valid. login.Email = "" and login.PasswordHash is still default
if (ModelState.IsValid && (!string.IsNullOrEmpty(login.Email) && !string.IsNullOrEmpty(login.PasswordHash)))
{
var user = await UserManager.FindAsync(login.Email, login.PasswordHash);
if (user != null)
{
await SignInAsync(user, true);
master.User = user;
return RedirectToAction("Overview", "Account", master);
}
}
return View(master);
}
I've also tried passing the entire MasterModel to the partial view instead (also changing the @model to use Models.MasterModel) whilst accessing the Login property as masterModel.Login.Email, etc, to no avail.
It's got to be something pretty simple that I'm missing with the binding on the property names, but I'm starting to go code blind now!
Any ideas?
[UPDATE] - Added AccountController