Kurz gesagt ich mag in der Lage sein, eine generische Ansichtsmodell in meine Ansichten passierenMVC generisches Ansichtsmodell
Hier einige vereinfachte Code des Kerns ist, was ich versuche
public interface IPerson
{
string FirstName {get;}
string LastName {get;}
}
public class FakePerson : IPerson
{
public FakePerson()
{
FirstName = "Foo";
LastName = "Bar";
}
public string FirstName {get; private set;}
public string LastName {get; private set;}
}
public class HomeViewModel<T>
where T : IPerson, new()
{
public string SomeOtherProperty{ get; set;}
public T Person { get; private set; }
public HomeViewModel()
{
Person = new T();
}
}
public class HomeController : Controller {
public ViewResult Index() {
return View(new HomeViewModel<FakePerson>());
}
}
Wenn ich zu erreichen schaffen sie meine Ansicht, wie alles funktioniert wie folgt erwartet
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<HomeViewModel<FakePerson>>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%: Html.DisplayFor(m=>m.Person.FirstName) %>
<%: Html.DisplayFor(m=>m.Person.LastName) %>
</asp:Content>
Allerdings möchte ich nicht direkt auf FakePerson in der Ansicht für den Fall ab, die ich einige andere IPerson Implementierung übergeben wollen, so dass ich versucht, die Seite Richtlinie
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<HomeViewModel<IPerson>>" %>
Aber natürlich zu ändern, die, nach einem ganzen Tag von Ausmisten etwa, ich habe mehr graue Haare und keine Ahnung, was als nächstes tun nicht funktionieren, so.
Kann jemand bitte helfen.
[UPDATE]
Einige beraten hat sugested, dass ich eine kovariante Schnittstelle verwendet werden soll; Definieren Sie eine nicht-generische Schnittstelle und verwenden Sie sie in der Ansicht. Leider habe ich das versucht, aber es gibt eine zusätzliche Implikation. Ich möchte die Htmlhelper Funktion können alle Daten Annotations Attribute zugreifen, die in der IPerson abgeleiteten Klasse definiert werden können
public class FakePerson : IPerson
{
public FakePerson()
{
FirstName = "Foo";
LastName = "Bar";
}
[DisplayName("First Name")]
public string FirstName {get; private set;}
[DisplayName("Last Name")]
public string LastName {get; private set;}
}
Während also eine kovariante Schnittstelle auf diese Weise funktioniert, teilweise, den abgeleiteten Typ für den Zugriff durch das ViewModel; Da die Ansicht in die Schnittstelle eingegeben wurde, scheinen die Attribute nicht zugänglich zu sein.
Gibt es in der Ansicht vielleicht einen Weg, Zugang zu diesen Attributen zu bekommen, vielleicht mit Reflektion. Oder könnte es einen anderen Weg geben, um die Ansicht zum Generischen zu schreiben.
Wie kann man erwarten, dass Ihre Sicht auf Zugang abgeleitet Daten, aber Sie wollen es nicht von den abgeleiteten Daten abhängig machen? Anders ausgedrückt: Wenn Sie auf Daten zugreifen, die nur für FakePerson gelten, hängt Ihre Ansicht von FakePerson ab. Daher sollten Sie Ihr Modell zu einem FakePerson machen. Wenn Sie ein anderes Objekt übergeben, wird es beim Zugriff auf den FakePerson Fehler geben. –
Sie können Datenannotationen auf keinen Fall mit Schnittstellen verwenden, da Attribute nicht vererbt werden (siehe http://stackoverflow.com/questions/540749/can-ac-sharp-class-inherit-attributes-from-its-interface) –