ASP.NET MVC - 创建新模型或使用Entity框架类

时间:2012-03-27 10:22:07

标签: asp.net-mvc entity-framework model-view-controller design-patterns

我正在开发一个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这样的字段,以便对此特定视图进行验证。

2 个答案:

答案 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");
}