ASP.NET MVC4视图中的模型和ItemModel绑定

时间:2013-06-26 16:06:18

标签: asp.net-mvc razor view model

我使用脚手架选项来创建SubscriptionController 以下是一些代码段:

In Controller:

public ActionResult Index()
{
    var subscriptions = db.Subscriptions;
    return View(subscriptions.ToList());
}

In View:

@model IEnumerable<Liquidity.Domain.Entity.Subscription>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Amount)
        </th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Amount)
        </td>    
        </td>
    </tr>
}
</table>

For my subscription model, I have:

public decimal Amount { get; set; }

以下是我的问题:

  1. 我认为Model绑定到Subscription列表而不是Subscription个身份,因为这是真的:

    @foreach(模型中的var项目)

    这是对的吗?

  2. 如果1是正确的,为什么在这一行:

    @Html.DisplayNameFor(model => model.Amount)

    模型会有Amount?这表明模型绑定到单个“订阅”。

  3. 对于这一行:

    @Html.DisplayFor(modelItem => item.Amount) 什么是modelItem和item绑定到?为什么lambda接受modelItem但不使用它?

  4. 请解释一下模型,型号和型号的确切含义。
    感谢。

1 个答案:

答案 0 :(得分:2)

  1. 这是对的。
  2. 正在使用DisplayNameFor的{​​{3}}重载。这允许您从IEnumerable模型中获取单个项目以显示列标题等内容。
  3. modelItem是您的模特。 item来自foreach。这有点像作弊,允许你使用DisplayFor助手。
  4. 有关第3项的更多信息。这适用于DisplayFor。但是,如果您想制作可编辑的网格EditorFor / TextboxFor,则会出现问题。 Razor将根据传入的表达式将名称分配给生成的HTML。因此,表中的所有项都将具有相同的名称。但是,要发布集合,名称必须包含索引,例如Item[0].AmountItem[1].Amount ....

    有两种方法可以完成这项工作。

    首先,使用for代替foreach。您需要将模型更改为支持索引器,IList,ICollection等的内容。这看起来像。

    @for(int i = 0; i < Model.Count; i++)
    {
        <tr>
            <td>
                @Html.EditorFor(model=> model[i].Amount)
            </td>    
            </td>
        </tr>
    }
    

    或者,我更喜欢,创建一个编辑器模板。在视图名称“EditorTemplates”中创建一个新文件夹。然后创建一个名为“Subscription.cshtml”的文件。此文件应如下所示

    @model Subscription
    <tr>
        <td>
            @Html.EditorFor(model=> model.Amount)
        </td>    
        </td>
    </tr>
    

    现在在您看来,您可以

    @Html.EditorFor(model => modle)
    

    @Html.EditorForModel()
    

    剃刀引擎非常聪明,可以重新定义您的模型是一个集合,它将为集合中的每个项目呈现EditorTemplate。此外,它将正确生成名称,因此您不必担心。使用此方法,您也可以继续使用IEnumerable模型。

    这也适用于DisplayTemplates。您只需将文件夹的名称更改为DisplayTemplates,然后使用DisplayFor代替EditorFor