在_Layout.cshtml上带有ViewModel的PartialView



我有一个布局页面,其中有一个部分视图。分部视图需要循环遍历视图模型上的一个属性,以显示类别列表。当显示一个类别时,我需要显示该类别中的文档列表。/Home/Index工作,但当我试图查看/Documents/Category/{id}时,我得到一个错误:

附加信息:传入字典的模型项的类型是'System.Collections.Generic.List ' 1[ViewModels. list]。,但是这个字典需要一个'ViewModels.HomeViewModel'类型的模型项。

_Layout.cshtml

... 
<body>
@Html.Partial("_CategoryViewModel")
<div class="content">
    @RenderBody()
</div>

HomeViewModel.cs

public class HomeViewModel {
    ...
    public ICollection<DocumentCategory> Categories { get; set; }
    public ICollection<Documents> Documents { get; set; }
    ...
}

_CategoryViewModel。cshtml(这应该显示所有类别的列表)

@model ViewModels.HomeViewModel
...
@foreach (DocumentCategory item in Model.Categories)
{
    <li>
        <a href="@Url.Action("Category", "Documents", new { @id = @item.CategoryId })" title="View documents in the @item.Name category">
            <span class="fa fa-files-o"></span>&nbsp;@item.Name
        </a>
    </li>
}

DocumentsController.cs

public ActionResult Category(int id)
{
    var thisCategory = _ctx.Categories.Get(c => c.CategoryId == id).FirstOrDefault();
    IEnumerable<DocumentViewModel> docs = null;
    if(thisCategory == null)
    {
        TempData.Add("errorMessage", "Invalid category");
    } else {
        docs = thisCategory.Documents.ToList();
    }
    return View("Category", docs);
}

正在发生的事情是有意义的-布局页面上的PartialView需要枚举在我使用的ViewModel中不存在的集合。我不知道如何实现这一点-唯一的方法似乎是添加一个类别属性,每个ViewModel在我的网站。

默认情况下,使用@Html.Partial()将把当前模型传递给局部视图,并且因为您的Category.cshtml视图使用@model List<DocumentViewModel>,那么List<DocumentViewModel>将传递给期望HomeViewModel的局部。

如果您想在每个页面上呈现HomeViewModel的部分视图,那么使用@Html.Action()调用返回部分

ChildActionOnly方法。
[ChildActionOnly]
public ActionResult Categories
{
    var model = new HomeViewModel()
    {
        .... // initialize properties
    }
    return PartialView("_CategoryViewModel", model)
}

和布局

@Html.Action("Categories", yourControllerName)
// or
@{ Html.RenderAction("Categories", yourControllerName); }

在我看来,你有几个不同的选择。

1。使用Html.Action并创建一个返回视图的Action

@Html.Action("Index", "Category") // Or your controller name.

相信这种方法有一些性能缺陷,因为为了呈现动作的结果,整个MVC生命周期将再次运行。但是,您可以在调用它的视图中没有正确的模型的情况下呈现操作的结果。

有人可能会认为这破坏了MVC模式,但这可能是值得的。


2。在您的_Layout.cshtml中使用通用模型(或接口),并让您的视图模型继承该模型。

在你的_Layout.cshtml:

@model IBaseViewModel

让你所有的视图模型实现这个接口。

public interface IBaseViewModel
{
    ICollection<DocumentCategory> Categories { get; set; }
}
public interface IBaseViewModel<T> : IBaseViewModel
{
    T ViewModel {get; set;}
}

由于您将@Html.Partial("_CategoryViewModel")放置在_Layout.cshtml中,我认为它应该在所有页面中可见,因此我认为使用_Layout.cshtml的所有控制器确保它获得所需的信息是合乎逻辑的,因此将Categories添加到模型中。

我一直使用这种方法来处理面包屑和菜单信息(在所有页面中使用的东西)。然后我有一个基本控制器,确保Categories填充正确的信息。

相关内容

  • 没有找到相关文章

最新更新