Insomma vorrei essere in grado di passare un ViewModel generica nelle mie opinioniMVC ViewModel generico
Ecco il codice semplificato del succo di quello che sto cercando di realizzare
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>());
}
}
Se io creare mio punto di vista come segue tutte le opere come previsto
<%@ 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>
Comunque io non voglio dipendere direttamente FakePerson nella vista nel caso in cui voglio passare qualche altra implementazione IPerson, così ho provato a cambiare la direttiva pagina
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<HomeViewModel<IPerson>>" %>
Ma, naturalmente, che non funziona, così, dopo un'intera giornata di pasticciare in giro, ho più capelli grigi e nessun indizio che cosa fare dopo.
Qualcuno può aiutare per favore.
[UPDATE]
Qualche consiglio ha sugested che dovrei usare un'interfaccia covariante; definire un'interfaccia non generica e utilizzarla nella vista. Unfortuanetly ho provato questo, ma c'è una implicazione adizionale. Vorrei la funzione HtmlHelper per poter accedere a qualsiasi attributi dati di annotazione che possono essere definite nella classe IPerson derivata
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;}
}
Così, mentre utilizzando un'interfaccia covariante questo modo funziona, in parte, per accedere al tipo derivato tramite il ViewModel; poiché la vista è stata digitata nell'interfaccia, sembra che gli attributi non siano accessibili.
C'è forse un modo, nella vista, per ottenere l'accesso a questi attributi, magari con la riflessione. Oppure potrebbe esserci un altro modo per digitare la vista sul generico.
Come ci si può aspettare l'immagine per l'accesso derivato dati, ma non vuoi farlo dipendere dai dati derivati? Mettiamola in un altro modo, se accedi ai dati che sono univoci per FakePerson, allora la tua vista dipende da FakePerson, e come tale dovresti rendere il tuo modello un FakePerson. Se passi in qualche altro oggetto, allora avrà degli errori all'accesso a FakePerson. –
Non è possibile utilizzare le annotazioni di dati con le interfacce in ogni caso, poiché gli attributi non sono ereditati (consultare http://stackoverflow.com/questions/540749/can-ac-sharp-class-inherit-attributes-from-its-interface) –