Es gibt keine stark typisierte View()-Methode, die ein ActionResult zurückgibt. Nehmen wir also an, ich habe
class Edit : ViewPage<Frob>
In meinem FrobController werde ich etwas tun wie "return View("Edit", someFrob);". Hier findet keine Überprüfung statt, so dass ich die Verwendung von View und Controller immer manuell synchronisieren muss. Das ist suboptimal, und mir sind keine eingebauten Lösungen bekannt.
Ich habe diese Methode zu meiner Controller-Basisklasse hinzugefügt:
public ActionResult ViewPage<V, M>(V view, M model)
where V : ViewPage<M>
where M : class {
return View(typeof(V).Name, model);
}
Anmerkung: Der Grund, warum ich einen Standpunkt vertrete Objekt, das nie verwendet wird, ist, weil, AFAIK, gibt es keine Möglichkeit, C#s Typ Inferenz anders funktioniert. Wenn ich den View-Parameter entfernen würde, müsste ich V explizit angeben, was auch bedeutet bedeutet, M explizit zu spezifizieren... seufz.
Jetzt kann ich das also tun:
return ViewPage(new Views.Frob.Edit(), myFrob);
Ich gebe die genaue Ansicht an (kein Problem, wenn sie umbenannt wird), und myFrob wird auf den richtigen Modelltyp geprüft. Der Nachteil ist, dass ich einen neuen Edit einfüge. Alternativ könnte ich auch schreiben:
return ViewPage((Views.Frob.Edit)null, myFrob);
Ein Nachteil ist, dass das Modell genau übereinstimmen muss. Mit einer ViewPage> kann ich also keine Liste einfügen. Ich dachte, dies könnte funktionieren:
public ActionResult ViewPage<V, M, T>(V view, T model)
where V : ViewPage<M>
where M : class
where T : M {
return View(typeof(V).Name, model);
}
Aber die Typinferenz von C# kann das nicht herausfinden. Das andere potenzielle Problem ist, dass der Name des Ansichtstyps möglicherweise nicht der richtige Name ist, da ich denke, dass er durch Attribute überschrieben werden kann. Aber das ist eine einfache Lösung, wenn ich darauf stoße.
Fragen:
- Wie kann ich diese Syntax sauberer gestalten?
- Welche Nachteile übersehe ich hier?
Edit: Was die Kenntnis des Controllers über den View betrifft, so ist sie nur geringfügig. Das einzige, was er von der View erhält, ist der Type, für den er den Namen abgreift. Das ist also gleichbedeutend mit der Übergabe des Strings name. Und das stark typisierte Modell, das übereinstimmen muss, sonst schlägt es fehl. Es weiß also nicht wirklich viel über den View - es ist nur ein Trick, um den Compiler dazu zu bringen, Fehler abzufangen.