请容忍我的菜鸟,我对 MVC 模式非常陌生。
我想做什么
我正在为我网站上的注册用户构建个人资料信息页面。此页面将列出有关用户的数据,例如出生日期、电话号码、订阅状态等。您明白了。我还想要一个表格让用户更改他们的密码、电子邮件地址、个人信息同页 .
我的问题
用户的数据通过传递的模型变量来自我的 Controller :
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。所以基本上我需要使用两种模型,一种用于输出信息,一种用于发布数据。我认为使用局部 View 可以实现这一点,但出现此错误:
The model item passed into the dictionary is of type 'Applicense.Models.User', but this dictionary requires a model item of type 'Applicense.Models.ProfileModel'.
这是我对局部 View 的调用:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
@Html.Partial("_ModifyProfileInfo")
}
这是部分 View :
@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; }
}
我错过了什么吗?这样做的正确方法是什么?
编辑:
我重新编写了反射(reflect) Nikola Mitev 答案的代码,但现在我遇到了另一个问题。这是我得到的错误:
Object reference not set to an instance of an object. (@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; }
}
Controller :
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
列到数据库中。编辑 2:
我的 Profile 操作的 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 Controller ,viewModel 是您要传递给 View 的多个对象的包装类。
public class ProfileUserViewModel
{
public ProfileModel ProfileModelObject {get; set;}
public UserModel UserModelObject {get; set;}
}
您的 Controller 应如下所示:
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>
}
关于asp.net - MVC 4 - 在局部 View 中使用不同的模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17173204/