2009-04-14 9 views

Antwort

4

Ich empfehle in den meisten Fällen die Verwendung eines separaten Präsentationsmodelltyps. Abgesehen von der Frage der Bindung (was wichtig ist, aber es gibt auch andere Möglichkeiten, um dieses Problem), denke ich, dass es andere Gründe, warum Typen Präsentationsmodell ist eine gute Idee:

  • Präsentationsmodelle erlauben „view- erste "Entwicklung. Erstellen Sie gleichzeitig eine Ansicht und ein Präsentationsmodell. Lassen Sie sich von Ihrem Benutzervertreter Feedback zur Ansicht geben. Iterate, bis Sie beide glücklich sind. Schließlich, lösen Sie das Problem der Zuordnung zurück zum "echten" Modell.
  • Präsentationsmodelle entfernen Abhängigkeiten, die das "echte" Modell haben könnte, was ein einfacheres Komponententesten von Controllern ermöglicht.
  • Präsentationsmodelle haben dieselbe "Form" wie die Ansicht selbst. Sie müssen also in der Ansicht keinen Code schreiben, um sich mit "Detailobjekten" und ähnlichem zu beschäftigen.
  • Einige Modelle können nicht in einem Aktionsergebnis verwendet werden. Zum Beispiel kann ein Objektdiagramm, das Zyklen enthält, nicht zu JSON serialisiert werden.
+0

Eigentlich möchte ich das tun, aber wo definiere ich diese Klassen? Wie genau zu implementieren? bindet der Modellbinder diese Klassen? – zsharp

+0

Ich habe sie in den Ordner Modelle der MVC-Anwendung. Das "echte" Modell (mein Entity Framework-Modell) wird in einer separaten Assembly erstellt. Ja, das Modellbinder kann an diese Typen binden. Manchmal ist das Modell der Benutzer-POSTs dasselbe wie das Präsentationsmodell, manchmal nicht. –

6

Ich bin gekommen, um die Idee zu mögen, Schnittstellen zu verwenden, um zu trennen, welche Eigenschaften enthalten sein sollten, wenn das Objekt aktualisiert wird.

Zum Beispiel:

zu erstellen und eine Person Objekt zu aktualisieren:

interface ICreatePerson 
{ 
    string Name { get; set; } 
    string Sex { get; set; } 
    int Age { get; set; } 
} 

interface IUpdatePerson 
{ 
    string Name { get; set; } 
} 

class Person : ICreatePerson, IUpdatePerson 
{ 
    public int Id { get; } 
    public string Name { get; set; } 
    public string Sex { get; set; } 
    public int Age { get; set; } 
} 

Dann, wenn Modells Bindung, nur die entsprechenden Schnittstelle als Typ verwenden und es wird nur die Namen Eigenschaft aktualisieren. Hier

ist ein Beispiel Controller-Methode:

public ActionResult Edit(int id, FormCollection collection) 
{ 
    // Get orig person from db 
    var person = this.personService.Get(id); 

    try 
    { 
     // Update person from web form 
     UpdateModel<IUpdatePerson>(person); 

     // Save person to db 
     this.personService.Update(person); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     ModelState.AddModelErrors((person.GetRuleViolations()); 

     return View(person); 
    } 
} 

Siehe this article (und Kommentare) für eine sehr gute Diskussion der Optionen.

+0

so in der Action Methode Sie zuerst die gesamte ‚Person‘ in dem Methodenparameter, akzeptieren und dann mit Update filtern? – zsharp

+0

Im Allgemeinen, nein. Die UpdateMethode verwendet die Formularwerte hinter den Kulissen. Angesichts des begrenzten Platzes in den Kommentaren habe ich die Antwort mit einer Beispielmethode aktualisiert. –

+0

Sie können auch die Formcollection zu Updatemodel() übergeben, die ohne spöttische für Unit-Tests ermöglicht. –

Verwandte Themen