【问题标题】:How to configure a ViewModel and Partial Page to include an IEnumerable如何配置 ViewModel 和部分页面以包含 IEnumerable
【发布时间】:2017-05-11 13:38:08
【问题描述】:

我正在尝试将我的 ASP.NET MVC 项目从直接视图和模型更改为使用 ViewModel 中间层。基本上,我所做的包括让 Person 与零个或多个 Events 相关联。我正在更改为 ViewModel,因为我想在 Person 详细信息页面上放置一个部分视图,以显示所有相关的 Events

我有一个 Person 模型类和一个用于 Event 的模型类,这是我的 ViewModel:

public class PersonEventViewModel
{
    public PersonEventViewModel(Person person)
    {
        Person = person;
    }

    public Person Person { get; set; }
    public IEnumerable<Event> Events { get; set; }

}

这对于转换我的单个记录页面非常有效。在诸如 Person Details 之类的页面上,我不得不将 @Html.DisplayFor(model =&gt; model.CreatedOn) 之类的行更改为 @Html.DisplayFor(model =&gt; model.Person.CreatedOn) 以便它可以正确找到属性,但它确实有效。然而,在我试图制作的局部视图中,我似乎无法让它们在那里显示模型的属性。它看起来或多或少是这样的:

@model IEnumerable<Proj.ViewModels.PersonEventViewModel>

<table class="table">
    <tr>
        <th>@Html.DisplayNameFor(model => model.RecordedOn)</th>
        <th>@Html.DisplayNameFor(model => model.RecordedBy)</th>
        <th>@Html.DisplayNameFor(model => model.Comments)</th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>@Html.DisplayFor(modelItem => item.RecordedOn)</td>
        <td>@Html.DisplayFor(modelItem => item.RecordedBy)</td>
        <td>@Html.DisplayFor(modelItem => item.Comments)</td>
    </tr>
}

这在直接使用事件模型时有效,但现在我在model 和属性之间添加什么似乎并不重要,它总是告诉我它无法解决它。

另外,我不确定如何将 ViewModel 传递给局部视图。我还没想好要放什么:

@Html.RenderPartial("_PersonEventList", ?????)

我尝试传递模型或模型信息的各种尝试都遇到了错误。


根据请求,这是我的详细信息页面的来源,我试图在其中放置事件的部分视图。

@model Proj.ViewModels.PersonEventViewModel
@{ ViewBag.Title = "Details"; }
<h2>Details</h2>
<div>
    <h4>Person</h4> <hr/>
    <dl class="dl-horizontal">
        <dt>@Html.DisplayNameFor(model => model.Person.FirstName)</dt>
        <dd>@Html.DisplayFor(model => model.Person.FirstName)</dd>
        @*...and so on through the fields...*@
    </dl>
</div>
<p> @Html.ActionLink("Edit Record", "Edit", new {id = Model.Person.PersonId}) </p>

@Html.RenderPartial("_PersonEventList", Model)

【问题讨论】:

  • 你试过这样@Html.RenderPartial("_PersonEventList", (List)ViewBag.data)
  • 我没有,但这仍然给我一个错误,类似于它之前所说的:Cannot implicitly convert type 'void' to 'object'. Expression must return a value to render.
  • 试试这样的,@Html.Partial("View", Model); @{Html.RenderPartial("viewName", Model));}
  • 是的,那也没用。关于void to object 的第一部分相同,然后是Argument type 'Proj.ViewModels.PersonEventViewModel' is not assignable to model type 'IEnumerable&lt;Proj.ViewModels.PersonEventViewModel&gt;'
  • 显示查看页面的完整代码你在哪里调用了@Html.RenderPartial

标签: asp.net-mvc partial-views asp.net-mvc-viewmodel


【解决方案1】:

假设您想要在您的部分中使用“事件”,部分应该采用 List&lt;Event&gt; 作为它的模型:

@model IEnumerable<Event> (or List<Event>)

然后在你的主视图中:

@Html.RenderPartial("_PersonEventList", Model.Events)

【讨论】:

  • 所以我读到的所有地方(SO 和其他地方)似乎都说这样的数据应该通过强类型的 ViewModel 传递,但这看起来你是在建议回到模型本身.还是我错过了什么?
  • 另外,我尝试切换到您建议的代码,但如果我使用RenderPartial 命令,我会得到无处不在的Cannot implicitly convert type 'void' to 'object' 错误(它什么也没告诉我)。如果我把它留在@Html.Partial 那么它似乎没问题。无法弄清楚原因,但由于我无法让局部视图工作,我不知道它是否会有所作为。
  • 只执行@Html.Partial("_PersonEventList", Model.Events) 会发生什么?
  • 我收到一个神秘错误:Unable to create a constant value of type 'Proj.Models.Person'. Only primitive types or enumeration types are supported in this context. 在尝试查看“人员详细信息”页面(部分视图所在的位置)时会发生这种情况。其他一切似乎都正常。
【解决方案2】:

正如@Barry Franklin 所说,您应该更改您的部分以接受事件列表。我想提的另一件事是,您可能应该使用 Partial 而不是 RenderPartial。 RenderPartial 需要用括号括起来并带有 ;在它的最后,以便它工作 (Html.Partial vs Html.RenderPartial & Html.Action vs Html.RenderAction)。

@Html.Partial("_PersonEventList", Model.Events)

你还需要更新部分代码:

    @model IEnumerable<Proj.ViewModels.Event>

<table class="table">
@foreach (var item in Model) {
    <tr>
        <td>@Html.DisplayFor(modelItem => item.RecordedOn)</td>
        <td>@Html.DisplayFor(modelItem => item.RecordedBy)</td>
        <td>@Html.DisplayFor(modelItem => item.Comments)</td>
    </tr>
}

【讨论】:

  • 首先,@model IEnumerable&lt;Proj.ViewModels.Event&gt; 不起作用,因为没有名为 Event 的 ViewModel。如果我将其设为 PersonEventViewModel,那么它会说没有任何称为 Event 或 Events 的东西。如果我将它设为 Proj.Models.Event,那么 Visual Studio 一切正常,它甚至似乎运行良好,直到我尝试查看详细信息页面。然后它在@foreach (var item in Model) { 行上抛出错误Unable to create a constant value of type 'Proj.Models.Person'. Only primitive types or enumeration types are supported in this context.。不知道这个错误是什么意思。
  • 只需将其替换为您的事件模型所在的命名空间
  • 我只是补充说,作为一个例子,你可以根据你的项目调整需要什么
  • 我认为最主要的一点是你如何使用 RenderPartial,如果你不想像这样@{ Html.RenderPartial() } 那样使用 Html.Partial
  • 我做到了,但我得到了那个奇怪的unable to create a constant value... 错误。对此有什么想法吗?我没有在网上找到任何有用的东西。
猜你喜欢
  • 1970-01-01
  • 2021-02-12
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多