我正在开发一个ASP.NET MVC 3应用程序,我首先使用实体框架代码来创建我的应用程序的类,并且我还有一个存储库以便对其执行操作,保持DBContext的清洁和DBEntities定义。
我的疑问是关于视图的渲染以及保存编辑模型的方式。
如果我有这个实体代表存储在我的数据库中的用户:
//Entity:
public class User
{
[Key]
public int IdUser { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
我想显示一个包含FirstName,LastName,Email和NewPassword,ConfirmPasword和CurrentPassword的视图,以便让用户更改他的数据,输入CurrentPassword来确认更改,所以我的疑问是,像ConfirmPasword一样和CurrentPassword不在我的实体中,所以我需要为此View创建一个新模型,并将我想要的信息从我的新模型复制到我的数据库实体以保存它?像:
public class UpdateUserModel
{
[Required]
[Display(Name = "Name")]
public string FirstName{ get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName{ get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Not valid email")]
public string Email { get; set; }
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPasword{ get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm the New Pasword")]
[Compare("NewPasword", ErrorMessage = "Password doesn´t mach.")]
public string ConfirmPasword{ get; set; }
[Required(ErrorMessage = "Need to specify the current password to save changes")]
[DataType(DataType.Password)]
[Display(Name = "Current Password")]
public string CurrentPassword { get; set; }
}
在我做的控制器中:
public ActionResult UpdateUser(UpdateUserModel model)
{
User u = (User)Membership.GetUser();
u.FirstName = model.FirstName;
u.LastName = model.LastName;
u.Email = model.Email;
if (!String.IsNullOrEmpty(model.NewPassword))
{
u.Password = FormsAuthentication.HashPasswordForStoringInConfigFile(model.NewPassword.Trim(), "md5");
}
repository.UpdateUser(u);
return View();
}
有任何方法可以使用如下控制器:
public ActionResult UpdateUser(User u)
{
repository.UpdateUser(u);
return View();
}
因为如果我有,我如何添加像ConfirmPassword或CurrentPassword这样的字段,以便对此特定视图进行验证。
答案 0 :(得分:6)
如果我是你,我不会在我的表示层使用域模型。我将创建一个视图模型(另一个类),它将与我的域模型非常相似。然后我会使用自动映射工具从我的域模型映射到视图模型。
这是一种非常常见的情况,因此,如果您使用谷歌“视图和域名”模型,您应该找到所需的一切。
public class User {
[Key]
public int IdUser { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
public class UpdateUserViewModel {
// Original fields
public string Password { get; set; }
public string PasswordConfirmation { get; set;
}
然后,您可以配置自动映射器以删除锅炉铭牌代码:
public ActionResult ShowUser()
{
var domainModel = new User(); // I'm assuming that properties are set somewhere
var viewModel = new UserViewModel();
Autommaper.Map(domainModel, viewModel);
return View(viewModel);
}
这非常粗糙,但希望你能有所了解。
更新1:**
据我了解,最好为每个视图创建一个新模型,然后将其映射到实体
它不仅更好,它提供了更好的关注点分离,使您的代码易于测试。只要查看类的名称,我就可以看到它的用途UpdateUserViewModel,RegisterUserViewModel等。
这个类中的原始字段应该是带有验证的元数据,而那些东西不是?
我的意思是原始字段:
public class UserViewModel{
public string UserName { get; set; }
public string FirstName { get; set; }
}
这些字段已经在您的User类中,所以我通过不再输入它来节省我的时间。
这会将我的模型从MVC更改为MVVM还是因为我仍然有控制器?
我相信我所建议的仍然是MVC模式,而不是MVVM。
关于Automaper,您使用的是github.com/AutoMapper/AutoMapper吗?
Automapper是我用过的东西。那里有很少的工具,它们几乎完全相同。尝试一下,找一个最符合你要求的。
祝你好运。答案 1 :(得分:1)
通常我会将区域用于项目的不同部分,除了放置这些额外代码的位置。
您将要在模型文件夹中添加一个viewmodel.cs类。在此类中,将包含有关如何在视图中建模数据的定义。这些视图模型将反映您希望用户与之交互的实体部分。交互将通过[HttpGet]
在控制器中完成,您可以在其中传递要与之交互的视图模型,然后[HttpPost]
将模型发回,然后将其映射到实体。
ViewModels.cs:
public class UserViewModel
{
public string UserName { get; set; }
}
SomeController:
public ActionResult getView()
{
var uvm = new UserViewModel();
return View(uvm);
}
查看getView.cshtml:
@model project.namespace.UserViewModel
@using (Html.BeginForm())
{
@Html.EditorFor(m => m.UserName)
<input type="submit" value="New User Name" />
}
回到控制器:
[HttpPost]
public ActionResult getView(UserViewModel model)
{
var entity = new ActualEntity();
entity.username = model.UserName;
//more mapping
//commit changes somewhere
return RedirectToAction("getView");
}