为什么我的视图模型无法与实现接口的通用 ViewModel 绑定? (ASP.NET MVC 3)
我试图向我的视图传递以下 ViewModel 的实例:
public class CompanyListViewModel<T> where T : ICompany
{
public IEnumerable<T> CompanyList;
public IEnumerable<string> StateList;
public CompanyListViewModel(IEnumerable<T> list)
{
CompanyList = list;
}
}
其中视图采用如下所示的内容:
@model Project.ViewModels.CompanyViewModels.CompanyListViewModel<ICompany>
我的控制器代码将如下所示的内容传递给视图:
CompanyListViewModel<ICompanyInListAsUser> model = new CompanyListViewModel<ICompanyInListAsUser>(_companyService.FilterByCompanyState(state));
其中 ICompanyInListAsUser
接口实现 ICompany
界面。 _companyService.FilterByCompanyState(state))
类返回 Company
对象的 IEnumerable
,该对象又实现 ICompanyInListAsUser
> 界面。
由于某种原因,我在访问视图时收到以下错误:
传递到字典中的模型项的类型为“Project.ViewModels.CompanyViewModels.CompanyListViewModel`1[Project.ViewModels.CompanyViewModels.ICompanyInListAsUser]”,但是这个字典需要类型为“Project.ViewModels.CompanyViewModels.CompanyListViewModel`1[Project.ViewModels.CompanyViewModels.ICompany]”的模型项。
如果 ICompanyInListAsUser
接口 < em>实际上实现了ICompany
吗?
任何帮助将不胜感激。
谢谢。
编辑
我还想说明我在这里想要实现的目标。假设我的应用程序中有多个访问级别(例如用户和管理员)。如果我的 Company
对象中有一个仅供管理员使用的属性,该怎么办?在这种情况下,我的 ICompanyInListAsUser
将包含我想要作为列表中的列的所有属性,除了仅限管理的属性。
因此,我的计划是将基本公司接口的 ViewModel
作为 IEnumerable
传入,并从控制器(或服务层)有选择地填充 IEnumerable
> 使用这些“过滤器”接口之一的实例,例如 ICompanyInListAsUser
。
希望这是有道理的,如果我需要详细说明,请告诉我。
I'm trying to pass my View an instance of the following ViewModel:
public class CompanyListViewModel<T> where T : ICompany
{
public IEnumerable<T> CompanyList;
public IEnumerable<string> StateList;
public CompanyListViewModel(IEnumerable<T> list)
{
CompanyList = list;
}
}
Where the View takes something like so:
@model Project.ViewModels.CompanyViewModels.CompanyListViewModel<ICompany>
And my controller code passes something like this to the View:
CompanyListViewModel<ICompanyInListAsUser> model = new CompanyListViewModel<ICompanyInListAsUser>(_companyService.FilterByCompanyState(state));
Where the ICompanyInListAsUser
interface implements the ICompany
interface. The _companyService.FilterByCompanyState(state))
class returns an IEnumerable
of Company
objects, which in turn, implement the ICompanyInListAsUser
interface.
For some reason, I receive the following error when accessing my View:
The model item passed into the dictionary is of type 'Project.ViewModels.CompanyViewModels.CompanyListViewModel`1[Project.ViewModels.CompanyViewModels.ICompanyInListAsUser]', but this dictionary requires a model item of type 'Project.ViewModels.CompanyViewModels.CompanyListViewModel`1[Project.ViewModels.CompanyViewModels.ICompany]'.
Why am I receiving this error if the ICompanyInListAsUser
interface does in fact implement ICompany
?
Any assistance would be greatly appreciated.
Thanks.
EDIT
I also wanted to state what I'm trying to achieve here. Say I have several access levels in my application (ex. User and Admin). What if I have a property in my Company
object that is admin-only? Well in that case, my ICompanyInListAsUser
would include all properties I wanted as columns in the list except the admin-only property.
So my plan here was to pass in as the ViewModel
an IEnumerable
of base company interface and from the controller (or service layer) selectively populate the IEnumerable
with an instance of one of these "filter" interfaces like ICompanyInListAsUser
.
Hopefully this makes sense, please let me know if I need to elaborate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您想要完成的任务应该可以通过使用 ViewModel 类的 Interface 并将 Generic 类型声明为 Covariant 来实现。像这样:
这样您也可以使用抽象类而不是 Company 的接口。
What you're trying to accomplish should be possible by using an Interface for the ViewModel class and declaring the Generic type as Covariant. Like this:
That way you could also get away with an abstract class instead of an interface for Company.
当您考虑这种情况时,请考虑接口无法提供实现,并且很明显您需要使用您希望泛型类进行操作的特定接口来关闭泛型类型。
如果不明显,那么,请进一步考虑,从纯 OOP 的角度来看,接口无法定义实现,只有类可以,并且 C# 不允许指定重叠的接口。
在我看来,您正试图将接口视为抽象基类。
Consider that interfaces cannot provide implementations when you think about this situation and it should become apparent that you need to close your generic type with the specific interface you want the generic class to operate upon.
If it's not apparent, well, consider further that from a pure OOP standpoint, interfaces can't define implementations, only classes can, and that C# doesn't allow you to specify overlapping interfaces.
It sounds to me like you are trying to treat an interface like an abstract base class.