4 Stimmen

Meine benutzerdefinierte ASP.NET MVC-Entitätsbindung: Ist sie eine gute Lösung?

Angenommen, ich möchte die Auswahl unserer Entität (aus einer Dropdown-Liste usw.) auf einer Seite, z. B. "Produkt", ermöglichen. Als Ergebnis könnte ich dies erhalten:

public ActionResult SelectedAction(Guid productId)
{
}

Aber ich möchte die Leistung von Modellbindern nutzen, also schreibe ich stattdessen Modellbinder, um mein Produkt aus dem Repository zu holen und verwende stattdessen

public ActionResult SelectedAction(Product product)
{
   if (ModelState.IsValid) {} else {}
}

Mein Model Binder setzt den Modellstatus auf false, wenn das Produkt ungültig ist. Nun, es gibt Probleme mit diesem Ansatz:

  1. Es ist nicht immer einfach, stark typisierte Methoden wie Html.ActionLink(c => c.SelectedAction(id)) zu verwenden, da wir Product und nicht id übergeben müssen.
  2. Es ist sowieso nicht gut, Entitäten als Controller-Parameter zu verwenden.
  3. Wenn der Modellstatus ungültig ist und ich zurückleiten und einen Fehler anzeigen möchte, kann ich das ausgewählte Produkt nicht beibehalten! Denn das gebundene Produkt ist nicht festgelegt und meine ID ist nicht vorhanden. Ich würde gerne RedirectToAction(c => c.Redisplay(product)) machen, aber das ist natürlich nicht möglich.

Jetzt scheint es, als müsste ich wieder "Guid productId" als Parameter verwenden... Allerdings gibt es eine Lösung, die ich gerne vorstellen und diskutieren möchte.

   public class EntityViewModel<T> where T : BaseEntity
   {
      public EntityViewModel(Guid id)
      {
         this.Id = id;
      }

      public static implicit operator EntityViewModel<T>(T entity)
      {
         return new EntityViewModel<T>(entity.Id);
      }

      public override string ToString()
      {
         return Id.ToString();
      }

      public Guid Id { get; set; }
      public T Instance { get; set; }
   }

Nun, wenn ich

public ActionResult SelectedAction(EntityViewModel<Product> product)
{
   if (ModelState.IsValid) {} else {}
}

sind alle Probleme gelöst:

  1. Ich kann EntityViewModel mit nur Id gesetzt übergeben, wenn ich nur Id haben.
  2. Ich verwende keine Entität als Parameter. Außerdem kann ich kann EntityViewModel als Eigenschaft innerhalb eines anderen ViewModel verwenden.
  3. Ich kann das EntityViewModel an RedirectToController zurückgeben und es wird seinen Id-Wert behalten, der sein wird Benutzer zusammen mit den Validierungsmeldungen (dank MVCContrib und ModelStateToTempData / PassParametersDuringRedirect) wieder angezeigt wird.

Der Modellbinder holt sich die Instanz aus dem Repository und setzt Modellstatusfehler wie "Nicht in der Datenbank gefunden" und so weiter. Und ich kann Dinge wie ActionLink(c => c.Action(Model.MyProductViewModelProperty)) verwenden.

Die Frage ist, ob es hier irgendwelche Nachteile gibt. Ich kann nichts Schlechtes erkennen, aber ich bin noch neu in MVC und könnte einige wichtige Dinge übersehen. Vielleicht gibt es bessere und bewährte Wege? Vielleicht ist das der Grund, warum jeder Entity-IDs als Eingabeparameter und Eigenschaften verwendet?

2voto

LondonBasedEngineer Punkte 655

Insgesamt scheint mir das ein guter Ansatz zu sein...

Als Alternative könnten Sie POCO für Ihr Viewmodel verwenden, dann denke ich, dass alle 3 Probleme automatisch gelöst werden würden. Haben Sie das Automapper-Projekt gesehen, das einen Entity-to-DTO-Ansatz ermöglicht? Dies würde Ihnen mehr Flexibilität geben, indem Sie Ihr ViewModel von Ihrem EntityModel trennen, aber das hängt wirklich von der Komplexität der Anwendung ab, die Sie erstellen.

MVC's ViewDataExtensions könnte auch nützlich sein, anstatt benutzerdefinierte Container zu erstellen, um verschiedene Viewmodel-Objekte zu halten, wie Sie in Nummer 2 erwähnen.

MVCContrib's ModelStateToTempData sollte für jedes serialisierbare Objekt funktionieren (muss für alle Sessionstate-Provider außerhalb des Prozesses serialisierbar sein, z.B. SQL, Velocity usw.), also könnten Sie das auch ohne Wrapping Ihrer Entity-Klassen verwenden, oder?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X