I have a view pages that have different partial views with different models. I created a model class that will call other classes so i can use it on the main view page. But my problem is that when i try to change the password it gives me an error that i am passing in a model which i need to pass in another model. I believe i have my structure right but not sure what is causing this issue.
Main view:
@model Acatar.Models.ProfileModel
@{
ViewBag.Title = "ProfileAccount";
}
@{ Html.RenderAction("_PlayNamePartial"); }
@{ Html.RenderAction("_UsernamePartial", "Account");}
@{ Html.RenderAction("_TalentsPartial", "Account");}
@if (ViewBag.HasLocalPassword)
{
@Html.Partial("_ChangePasswordPartial")
}
else
{
@Html.Partial("_SetPasswordPartial")
}
Profile Model: containing models that i have created
public class ProfileModel
{
public LocalPasswordModel LocalPasswordModel { get; set; }
public PlayNameModel PlayNameModel { get; set; }
public UsernameModel UsernameModel { get; set; }
public TalentsModel TalentsModel { get; set; }
}
Controller:
public ActionResult Profile(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: "";
ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
ViewBag.ReturnUrl = Url.Action("Profile");
return View();
}
POST:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Profile(LocalPasswordModel model)
{
bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
ViewBag.HasLocalPassword = hasLocalAccount;
ViewBag.ReturnUrl = Url.Action("Profile");
if (hasLocalAccount)
{
if (ModelState.IsValid)
{
// ChangePassword will throw an exception rather than return false in certain failure scenarios.
bool changePasswordSucceeded;
try
{
changePasswordSucceeded = WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
}
catch (Exception)
{
changePasswordSucceeded = false;
}
if (changePasswordSucceeded)
{
return RedirectToAction("Profile", new { Message = ManageMessageId.ChangePasswordSuccess });
}
else
{
ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
}
}
}
else
{
// User does not have a local password so remove any validation errors caused by a missing
// OldPassword field
ModelState state = ModelState["OldPassword"];
if (state != null)
{
state.Errors.Clear();
}
if (ModelState.IsValid)
{
try
{
WebSecurity.CreateAccount(User.Identity.Name, model.NewPassword);
return RedirectToAction("Profile", new { Message = ManageMessageId.SetPasswordSuccess });
}
catch (Exception e)
{
ModelState.AddModelError("", e);
}
}
}
return View(model);
}
View Page for password change:
@model Project.Models.LocalPasswordModel
@using (Html.BeginForm("Profile", "Account")) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<fieldset>
<legend>Change Password Form</legend>
@Html.LabelFor(m => m.OldPassword)
@Html.PasswordFor(m => m.OldPassword)
@Html.LabelFor(m => m.NewPassword)
@Html.PasswordFor(m => m.NewPassword)
@Html.LabelFor(m => m.ConfirmPassword)
@Html.PasswordFor(m => m.ConfirmPassword)
<br/>
<input class="btn btn-small" type="submit" value="Change password" />
</fieldset>
The Error i am getting:
The model item passed into the dictionary is of type 'Project.Models.LocalPasswordModel', but this dictionary requires a model item of type 'Project.Models.ProfileModel'.