为列表中具有不同底层类型的项有条件地选择视图模型,而无需显式检查和强制转换每个项

本文关键字:模型 转换 检查和 视图 选择 列表 有条件 类型 | 更新日期: 2023-09-27 18:12:28

我有两个属于视图模型的视图,它们用于我网站上特定内容类型的清单。

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

我将搜索结果项作为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 );}
    }

有什么好的方法可以做到这一点吗?

为列表中具有不同底层类型的项有条件地选择视图模型,而无需显式检查和强制转换每个项

如果你不打算使用接口,你为什么要实现它们呢?只做:

foreach (ISearchInterfaceItem item in Model.SearchInterfaceItems)

(之后甚至不需要强制转换)

好消息是mvc有一些简单的方法。

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

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

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

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

如果你没有编辑,你也可以使用DisplayTemplates.