ric*_*rdo 8 asp.net generics asp.net-mvc viewmodel
总之,我希望能够将通用的ViewModel传递给我的视图
以下是我想要实现的目标的一些简化代码
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>());
}
}
Run Code Online (Sandbox Code Playgroud)
如果我按如下方式创建我的视图,则按预期工作
<%@ 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>
Run Code Online (Sandbox Code Playgroud)
但是,如果我想传递其他一些IPerson实现,我不希望在视图中直接依赖FakePerson,所以我尝试将页面指令更改为
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<HomeViewModel<IPerson>>" %>
Run Code Online (Sandbox Code Playgroud)
但当然这不起作用,所以,经过一整天的磨砺,我有更多的白发,不知道接下来该做什么.
请有人帮忙吗.
[UPDATE]
有人建议我应该使用协变接口; 定义非泛型接口并在View中使用它.不幸的是,我尝试了这一点,但有一个附带的含义.我希望HtmlHelper函数能够访问可能在IPerson派生类中定义的任何数据注释属性
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;}
}
Run Code Online (Sandbox Code Playgroud)
因此,在使用协变接口时,这种方式可以部分地通过ViewModel访问派生类型.由于视图是在界面上键入的,因此无法访问属性.
在视图中,是否有一种方法可以通过反射访问这些属性.或者可以在其他方面键入View到泛型.
你的代码几乎是正确的;你只需要在控制器中传递一个HomeViewModel<IPerson>(不是)。FakePerson
您还可以在视图中使用模型的协变接口,但这可能有点过头了。