2013-02-13 84 views
0

我有一個視圖頁面,它們與不同模型具有不同的局部視圖。我創建了一個模型類,它將調用其他類,以便我可以在主視圖頁面上使用它。但我的問題是,當我嘗試更改密碼時,它給了我一個錯誤,我正在傳遞一個模型,我需要在另一個模型中傳遞。我相信我的結構是正確的,但不知道是什麼導致了這個問題。視圖錯誤中的多個模型

主視圖:

@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") 
      } 

資料型號:包含模型我已經建立

public class ProfileModel 
    { 
     public LocalPasswordModel LocalPasswordModel { get; set; } 
     public PlayNameModel PlayNameModel { get; set; } 
     public UsernameModel UsernameModel { get; set; } 
     public TalentsModel TalentsModel { get; set; } 
    } 

控制器:

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); 
    } 

的密碼更改視圖頁:

@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 model item passed into the dictionary is of type 'Project.Models.LocalPasswordModel', but this dictionary requires a model item of type 'Project.Models.ProfileModel'.

+0

你在哪裏通過你的個人資料模型? – ssilas777 2013-02-13 18:21:00

+0

@ ssilas777在主視圖頁面 – BB987 2013-02-13 18:32:10

+0

但是從你的控制器你什麼也沒有傳 - View();你應該填充你的配置文件模型,並像查看(模型)一樣傳遞它。所有其他部分視圖都使用Renderaction,所以不會出錯,但在@ Html.Partial中它需要模型。跳它是有道理的 – ssilas777 2013-02-13 18:39:21

回答

0

嘗試在@Html.Partial方式識別模型。 (請原諒我的語法,我沒有一個IDE現在

 @if (ViewBag.HasLocalPassword) 
     { 
      @Html.Partial("_ChangePasswordPartial",Model.LocalPasswordModel) 
     } 
     else 
     { 
      @Html.Partial("_SetPasswordPartial",Model.LocalPasswordModel) 
     } 

(我猜第二種觀點也使用同一型號) 但我看不到任何模型傳遞到您的視圖從您的控制器,你應該通過一個模型來查看

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"); 

     var ProfileModel = new ProfileModel(); 
     ProfileModel.LocalPasswordModel = populateFromDB(); 
     return View(ProfileModel); 
    } 

或考慮設立一個行動的結果,你也做了這樣的其他局部視圖呈現此局部視圖。(如果有使用Html.partial這裏沒有其他意圖)

  @if (ViewBag.HasLocalPassword) 
      { 
       @Html.RenderAction("_ChangePasswordPartial") 
      } 
      else 
      { 
       @Html.RenderAction("_SetPasswordPartial") 
      } 
+0

當我嘗試這個 - 我會得到的錯誤:'對象引用沒有設置爲一個對象的實例.'當頁面加載 – BB987 2013-02-13 18:31:20

+0

正如在我以前的評論中,你沒有從你的控制器傳遞任何模型到你的主視圖,這是導致這個錯誤。 – ssilas777 2013-02-13 18:41:33

+0

正如我所做的這些更改,我的錯誤消息中的模型名稱仍然相同,但翻轉。 – BB987 2013-02-13 19:01:53