【发布时间】:2011-06-10 15:08:32
【问题描述】:
简而言之,我希望能够将通用 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>());
}
}
如果我按如下方式创建视图,则所有工作都按预期进行
<%@ 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>
但是,如果我想传递一些其他 IPerson 实现,我不想在视图中直接依赖 FakePerson,所以我尝试将页面指令更改为
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<HomeViewModel<IPerson>>" %>
但这当然行不通,所以,经过一整天的胡闹,我的头发越来越白,不知道下一步该做什么。
有人可以帮忙吗?
[更新]
有人建议我应该使用协变接口;定义一个非通用接口并在视图中使用它。不幸的是,我已经尝试过了,但还有一个额外的含义。我希望 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;}
}
因此,虽然以这种方式使用协变接口,但在某种程度上,它可以通过 ViewModel 访问派生类型;由于视图是输入到界面的,因此似乎无法访问属性。
在视图中是否有一种方法可以访问这些属性,也许是反射。 或者是否可以通过其他方式将 View 键入泛型。
【问题讨论】:
-
您怎么能期望您的视图访问派生数据,但又不想让它依赖于派生数据?换句话说,如果您访问 FakePerson 独有的数据,那么您的视图依赖于 FakePerson,因此您应该使您的模型成为 FakePerson。如果传入其他对象,则访问 FakePerson 时会出错。
-
无论如何你都不能对接口使用数据注解,因为属性不是继承的(见stackoverflow.com/questions/540749/…)
标签: asp.net asp.net-mvc generics viewmodel