2012-06-25 93 views
5

我有三个模型合并在一起创建一个视图模型,我希望能够在单击“编辑”时编辑该视图模型。我无法找到一个关于它如何工作(任何地方)的直接例子。如何从MVC3中的编辑页面更新视图模型?

我不确定我是否要走正确的道路。我能够获得数据的观点。此时,我无法保存它。

任何帮助,将不胜感激。

谢谢!

型号:

public class Person 
{ 
    [Key] 
    public int Id { get; set; } 

    [MaxLength(20)] 
    [Required(ErrorMessage = "First name is required.")] 
    public string FirstName { get; set; } 

    [MaxLength(20)] 
    [Required(ErrorMessage = "Last name is required.")] 
    public string LastName { get; set; } 
    [MaxLength(40)] 
    [Required(ErrorMessage = "Email is required.")] 
    public string Email { get; set; } 
    [MaxLength(20)] 
    [DataType(DataType.PhoneNumber)] 
    public string Phone { get; set; } 

    public bool Active { get; set; } 
} 


    public class ClientContact 
{ 
    [Key] 
    [ForeignKey("Person")] 
    public int ClientPersonId { get; set; } 
    public int ClientId { get; set; } 
    [MaxLength(40)] 
    public string Title { get; set; } 

    public Person Person { get; set; } 
    [ForeignKey("ClientId")] 
    public Client Client { get; set; } 
} 

    public class Client 
{ 
    [Key] 
    public int ClientId { get; set; } 
    public string Name { get; set; } 
    public bool Active {get;set;} 

} 

视图模型:

public class ClientContactViewModel 
{ 

    private SimplexDB db = new SimplexDB(); 


    public ClientContactViewModel() 
    { 

    } 


    public ClientContactViewModel(int id) 
    { 
     ClientPersonId = id; 
     InitializeClientContact(); 
    } 

    public int ClientPersonId { get; set; } 


    [Display(Name = "First Name")] 
    public string FirstName { get; set; } 
    [Display(Name = " Last Name")] 
    public string LastName { get; set; } 
    [Display(Name = "Title")] 
    public string Title { get; set; } 
    [Display(Name = "Email Address")] 
    public string Email { get; set; } 
    [Display(Name = "Phone")] 
    public string Phone { get; set; } 
    [Display(Name = "Client Name")] 
    public int ClientId { get; set; } 


    public SelectList Clients 
    { 
     get 
     { 
      return new SelectList(db.Clients, "ClientId", "Name"); 

     } 
    } 

    private void InitializeClientContact() 
    { 
     var contact = db.ClientPersons.Include("Person").Where(x => x.ClientPersonId == ClientPersonId).SingleOrDefault(); 
     if (contact != null) 
     { 
      FirstName = contact.Person.FirstName; 
      LastName = contact.Person.LastName; 
      Title = contact.Title; 
      Email = contact.Person.Email; 
      Phone = contact.Person.Phone; 
      ClientId = contact.ClientId; 

     } 
    } 



} 

控制器:

   public class ClientContactController : Controller 
    { 
     private database db = new database(); 

// 
     // GET: /ClientContact/Edit/5 

     public ActionResult Edit(int id) 
     { 
      return View(new ClientContactViewModel(id)); 
     } 

     // 
     // POST: /ClientContact/Edit/5 

     [HttpPost] 
     public ActionResult Edit(ClientContactViewModel model) 
     { 
      if (ModelState.IsValid) 
      { 
       db.Entry(model).State = EntityState.Modified; 
       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 
      return View(model); 
     } 
} 

我在db.Entry(模型)得到一个错误.STATE ......“实体类型ClientContactViewModel不是当前上下文模型的一部分。“

回答

9

您的ViewModel不是一个实体。您应该将您的ViewModel映射到您的实体,然后将实体的状态设置为已修改。

基本上,这意味着你应该用你的视图模型值来设置你的实体值。您可以使用AutoMapper或手动处理:

[HttpPost] 
    public ActionResult Edit(ClientContactViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      ClientContact contact = db.ClientPersons.Include("Person") 
            .Where(x => x.ClientPersonId == model.ClientPersonId) 
            .SingleOrDefault(); 
      contact.FirstName = model.FirstName; 
      // etc 
      db.Entry(contact).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(model); 
    } 

一个极好的方法请参见http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/在MVC使用的ViewModels。

此外,我强烈建议不要在ViewModel中进行任何数据访问。在控制器中执行该操作,或者更好地在Controller中使用的存储库中执行此操作。模型绑定对于具有逻辑的模型并不能很好地发挥作用(即它们不应该包含比简单的get/set属性更多的东西)。

+0

我该怎么做呢?对不起,我是新手。 –

+0

查看我更新的答案。 – jrummell

+0

要清楚,我是否需要基于上面编写的代码更新我的视图模型?谢谢你的帮助。 –

1

您需要将模型的属性移至GET操作中的viewmodel。在POST操作中,从数据库获取原始模型,使用视图模型中的数据更新模型,然后保存更改。您的模型基本上是数据库中表的表示形式。您的视图模型就是屏幕上显示的内容。

[HttpPost] 
    public ActionResult Edit(ClientContactViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 

      var client = db.Client.Where(c => c.Id = model.ClientPersonId); 
      client.FirstName = model.FirstName; 

      ...etc through all your properties and other models... 


      db.Entry(model).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(model); 
    } 

有雨衣方法可以做到这一点,但是这代表没有抽象的想法。