Asp.net
MVC 4 - 在局部視圖中使用不同的模型
請忍受我的菜鳥,我對 MVC 模式非常陌生。
我正在嘗試做的事情
我正在為我的網站上的註冊使用者建構個人資料資訊頁面。此頁面將列出有關使用者的數據,例如出生日期、電話號碼、訂閱狀態等。你明白了。我還想有一個表格讓使用者在同一頁面上更改他們的密碼、電子郵件地址、個人資訊。
我的問題
使用者的數據通過傳遞的模型變數來自我的控制器:
public ActionResult Profil() { var model = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName); return View(model); }在我看來,輸出如下所示:
<label>Phone number: </label> @if (Model.PhoneNumber != null) { @Model.PhoneNumber } else { <span class="red">You haven't set up your phone number yet. </span> }使用者可以更改其資訊的表單將使用另一個模型 ProfileModel。所以基本上我需要在我的視圖中使用兩個模型,一個用於輸出資訊,一個用於發布數據。我認為使用局部視圖可以實現此目的,但出現此錯誤:
傳入字典的模型項的類型為“Applicense.Models.User”,但此字典需要“Applicense.Models.ProfileModel”類型的模型項。
這是我對局部視圖的呼叫如下所示:
@using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary() @Html.Partial("_ModifyProfileInfo") }這是部分視圖:
@model Applicense.Models.ProfileModel <ul> <li> @Html.LabelFor(m => m.Email) @Html.EditorFor(m => m.Email) </li> <li> @Html.LabelFor(m => m.ConfirmEmail) @Html.EditorFor(m => m.ConfirmEmail) </li> <input type="submit" value="Update e-mail" /> </ul>最後是我的 ProfileModel:
public class ProfileModel { [Required] [DataType(DataType.EmailAddress)] [Display(Name = "New e-mail address")] public string Email { get; set; } [DataType(DataType.EmailAddress)] [Display(Name = "Confirm new e-mail address")] [Compare("Email", ErrorMessage = "The e-mail and it's confirmation field do not match.")] public string ConfirmEmail { get; set; } }我錯過了什麼嗎?這樣做的正確方法是什麼?
編輯: 我重新編寫了反映 Nikola Mitev 答案的程式碼,但現在我遇到了另一個問題。這是我得到的錯誤:
你呼叫的對像是空的。(@Model.UserObject.LastName)
這僅在我發布更改的電子郵件地址值時發生。這是我的 ViewModel (ProfileModel.cs):
public class ProfileModel { public User UserObject { get; set; } [Required] [DataType(DataType.EmailAddress)] [Display(Name = "Új e-mail cím")] public string Email { get; set; } [DataType(DataType.EmailAddress)] [Display(Name = "Új e-mail cím megerősítése")] [Compare("Email", ErrorMessage = "A két e-mail cím nem egyezik.")] public string ConfirmEmail { get; set; } [DataType(DataType.EmailAddress)] [Display(Name= "E-mail cím")] public string ReferEmail { get; set; } }控制器:
public ActionResult Profil() { var User = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName); var ProfileViewModel = new ProfileModel { UserObject = User }; return View(ProfileViewModel); }最後這是我的
user.cs模型課:[Table("UserProfile")] public class User { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } [Column("UserName")] public string UserName { get; set; } [Column("Email")] [Required] public string Email { get; set; } [Column("FirstName")] public string FirstName { get; set; } [Column("LastName")] public string LastName { get; set; } [Column("PhoneNumber")] public string PhoneNumber { get; set; } ... You get the idea of the rest...我認為它正在發生,因為模型試圖將每
required列中的數據放入數據庫中。Edit2: 我的 Profil 操作的 httppost 方法:
[HttpPost] [Authorize] [ValidateAntiForgeryToken] public ActionResult Profil(ProfileModel model) { if (ModelState.IsValid) { //insert into database return Content("everything's good"); } else { //outputs form errors return View(model); } }
處理這種情況的最佳方法是使用 viewModel 並將其傳遞給 Profile 控制器,viewModel 是要傳遞給視圖的多個對象的包裝類。
public class ProfileUserViewModel { public ProfileModel ProfileModelObject {get; set;} public UserModel UserModelObject {get; set;} }您的控制器應如下所示:
public ActionResult Profil() { var profileModel = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName); var userModel = //fetch from db. var pmViewModel = new ProfileUserViewModel { ProfileModelObject = profileModel, UserModelObject = userModel }; return View(pmViewModel); }最後你的觀點:
@model Applicense.Models.ProfileUserViewModel <label>Phone number: </label> @if (Model.ProfileModelObject.PhoneNumber != null) { @Model.PhoneNumber } else { <span class="red">You haven't set up your phone number yet. </span> }