有条件地为列表中具有不同基础类型的项目选择视图模型,而不显式检查和转换每个项目

时间:2014-07-10 21:48:54

标签: c# asp.net-mvc razor dynamic viewmodel

我有一些属于视图模型的视图,这些视图用于我网站上特定内容类型的列表。

我想在列出搜索结果时重用这些视图模型,其中这些内容类型在一个列表中一起显示。

我将搜索结果项目作为API项目, 然后我可以继续查找项目的基础类型并将它们映射到相应的视图模型(DocumentViewModel用于文档,NewsPageViewModel用于新闻页面等)。

我真正想做的是这样的事情:         将搜索匹配项映射到底层内容类型的正确视图模型。 然后将视图模型作为动态对象与指定其支持类型的属性以及视图路径/名称的属性一起返回。

    Model.dynamicItems =  new List<dynamic>()
    {document, newsPage};
    foreach(var item in Model.dynamicItems)
    {
            @{ Html.RenderPartial(item.viewName, (item.Type) item );}
    }

但据我所知,由于缺少鸭子打字,这是不可能的。

我想这样的事情可行,但感觉丑陋和重复:

public Interface ISearchInterfaceItem
{
    string viewName {get; set;}
}

public class DocumentViewModel : ISearchInterfaceItem 
{
    ...
}

public class NewsPageViewModel : ISearchInterfaceItem 
{
    ... 
}


Model.SearchInterfaceItems =  new List<ISearchInterfaceItem>()
{newsPageItem, document};

foreach(var item in Model.SearchInterfaceItems)
{
    if(item as DocumentViewModel != null)
    {
        @{ Html.RenderPartial(item.viewName, (DocumentViewModel) item );}
    }

    else if (item as NewsPageViewModel != null)
    {
        @{ Html.RenderPartial(item.viewName, (NewsPageViewModel) item );}
    }

有没有什么好方法可以实现这个目标?

2 个答案:

答案 0 :(得分:0)

如果您不打算使用接口,为什么要在世界上实现接口?只是做:

foreach (ISearchInterfaceItem item in Model.SearchInterfaceItems)

(之后你甚至不需要再投射。)

答案 1 :(得分:0)

好消息是mvc有一些简单的事情。

在共享文件夹中创建一个EditorTemplates文件夹。

- 在此文件夹中创建部分视图。

- 视图的名称应该是它显示的类型的名称。

- 在你的视图中调用EditorForModel辅助方法。

如果您不进行编辑,也可以使用DisplayTemplates。