【问题标题】:ASP.NET MVC - create a new Model or use a Entity framework classASP.NET MVC - 创建新模型或使用实体框架类
【发布时间】:2012-04-10 20:57:54
【问题描述】:

我正在开发一个 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 不在我的实体中,所以我需要为此视图创建一个新模型,并将我想要的信息从我的新模型复制到我的数据库实体以保存它?喜欢:

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 以便对此特定视图进行验证。

【问题讨论】:

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


    【解决方案1】:

    如果我是你,我不会在我的表示层中使用域模型。我将创建一个与我的域模型非常相似的视图模型(另一个类)。然后我会使用自动映射工具从我的域模型映射到视图模型。

    这是一种非常常见的情况,因此如果您在 Google 上搜索“视图和域”模型,您应该会找到所需的一切。

    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 是我用过的东西。那里的工具很少,它们做的事情几乎相同。尝试几个,然后找到最适合您要求的。

    祝你好运。

    【讨论】:

    • 好的,我明白了。据我了解,最好为每个视图创建一个新模型,然后将其映射到实体中。什么意思//原始字段,在这个类中应该是带有验证的元数据,而那些东西不是?这会将我的模型从 MVC 更改为 MVVM 还是因为我还有控制器?关于 Automaper,您使用的是github.com/AutoMapper/AutoMapper吗?
    • 那么我应该在哪里编写验证和元数据?在 UserViewModel 类中不是吗?
    • 好的,谢谢!我会这样做^^
    【解决方案2】:

    通常我将区域用于项目的不同部分,作为放置这些额外代码的位置。

    您几乎要在模型文件夹中添加一个 viewmodel.cs 类。在这个类中将保存您对如何在视图中建模数据的定义。这些视图模型将反映您希望用户与之交互的实体部分。交互将在控制器中通过[HttpGet][HttpPost] 在控制器中完成,通过[HttpPost] 将模型发回然后将其映射到实体。

    ViewModels.cs:

    public class UserViewModel
    {
     public string UserName { get; set; }
    }
    

    一些控制器:

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

    【讨论】:

    • 这或多或少是我现在所拥有的,问题是我想跳过将我的实体一直映射到模型视图的问题,反之亦然,但有了你的回答,我认为这是从实体到视图具有不同验证/属性的唯一方法。谢谢!
    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    相关资源
    最近更新 更多