2012-06-25 5 views
5

Tengo tres modelos que se unen para crear un modelo de vista y me gustaría poder editar ese modelo de vista al hacer clic en "editar". No puedo encontrar un ejemplo directo de cómo funciona esto (en cualquier lugar).¿Cómo actualizo un modelo de vista desde una página de edición en MVC3?

No estoy seguro de si voy por el camino correcto. Puedo obtener la vista con los datos. En este punto, no puedo guardarlo.

Cualquier ayuda sería apreciada.

Gracias!

Modelos:

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

} 

vista del modelo:

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; 

     } 
    } 



} 

controlador:

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

Me aparece un error en el db.Entry (modelo) .State ... " El tipo de entidad ClientContactViewModel no es parte del modelo para el contexto actual ".

Respuesta

9

Su ViewModel no es una entidad. Debe asignar su ViewModel a su entidad y luego establecer el estado de la entidad como modificado.

Básicamente, esto significa que debe establecer los valores de su entidad con los valores de su modelo de vista. Puede utilizar AutoMapper o manejarlo manualmente:

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

Ver http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ de un enfoque excelente para el uso en ViewModels MVC.

Además, recomendaría encarecidamente no hacer ningún acceso a datos en su ViewModel. Hazlo en tu Controlador, o incluso mejor, en un Repositorio que usa tu Controlador. El enlace de modelo no funciona bien con modelos que tienen lógica (es decir, no deberían contener nada más que simples propiedades de obtención/configuración).

+0

¿Cómo podría hacer eso? Lo siento, soy nuevo en esto. –

+0

Ver mi respuesta actualizada. – jrummell

+0

Para ser claro, ¿necesito actualizar mi modelo de vista en función del código que ha escrito arriba? Gracias por tu ayuda. –

1

Debe mover las propiedades de sus modelos al modelo de vista en la acción GET. En la acción POST, obtenga sus modelos originales del archivo base, actualice los modelos con los datos del modelo de vista y luego guarde los cambios. Sus modelos son esencialmente representaciones de tablas en su base de datos. Su modelo de vista es solo lo que se muestra en la pantalla.

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

Existen formas más simples de hacer esto, pero esto representa la idea sin abstracciones.

Cuestiones relacionadas