2012-06-25 6 views
5

Ich habe drei Modelle, die zusammenkommen, um ein Ansichtsmodell zu erstellen, und ich möchte dieses Ansichtsmodell bearbeiten können, wenn ich auf "Bearbeiten" klicke. Ich kann kein einfaches Beispiel dafür finden, wie das funktioniert (überall).Wie aktualisiere ich ein Ansichtsmodell von einer Bearbeitungsseite in MVC3?

Ich bin mir nicht sicher, ob ich den richtigen Weg gehe. Ich kann die Daten einsehen. An diesem Punkt kann ich es nicht speichern.

Jede Hilfe wäre willkommen.

Danke!

Modelle:

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

} 

Ansicht Modell:

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; 

     } 
    } 



} 

Controller:

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

Ich erhalte eine Fehlermeldung bei der db.Entry (Modell) .State ... " Der Entitätstyp ClientContactViewModel ist nicht Teil des Modells für den aktuellen Kontext. "

Antwort

9

Ihr ViewModel ist keine Entität. Sie sollten Ihr ViewModel Ihrer Entität zuordnen und dann den Status der Entität auf "Modified" setzen.

Grundsätzlich bedeutet dies, dass Sie Ihre Entity-Werte mit Ihren View-Modellwerten festlegen sollten. Sie können AutoMapper verwenden oder manuell handhaben:

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

Siehe http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ für einen ausgezeichneten Ansatz in MVC Viewmodel verwenden.

Auch würde ich sehr empfehlen, keinen Datenzugriff in Ihrem ViewModel zu machen. Tun Sie das in Ihrem Controller oder noch besser in einem Repository, das von Ihrem Controller verwendet wird. Die Modellbindung funktioniert nicht gut mit Modellen, die Logik haben (d. H. Sie sollten nichts mehr enthalten als einfache Get/Set-Eigenschaften).

+0

Wie würde ich das machen? Tut mir leid, ich bin neu in diesem Bereich. –

+0

Siehe meine aktualisierte Antwort. – jrummell

+0

Um klar zu sein, muss ich mein Ansichtsmodell basierend auf dem Code, den Sie oben geschrieben haben, aktualisieren? Danke für Ihre Hilfe. –

1

Sie müssen die Eigenschaften Ihrer Modelle in der GET-Aktion in das Ansichtsmodell verschieben. Rufen Sie in der POST-Aktion Ihre ursprünglichen Modelle aus der Datenbank ab, aktualisieren Sie die Modelle mit den Daten aus dem Ansichtsmodell, und speichern Sie anschließend die Änderungen. Ihre Modelle sind im Wesentlichen Darstellungen von Tabellen in Ihrer Datenbank. Ihr Ansichtsmodell ist genau das, was auf dem Bildschirm angezeigt wird.

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

Es gibt einfachere Möglichkeiten, dies zu tun, aber das ist die Idee ohne Abstraktionen.

Verwandte Themen