无法通过Html.BeginForm()将数据从视图传递到Action

时间:2015-07-22 11:50:14

标签: c# asp.net razor asp.net-mvc-5

我是asp.net mvc的新手,所以我失败的原因可能也是基本的,但是现在我工作近一天后似乎无法找到它。

我要做的是从索引视图中获取已编辑的模型,并将其传递给第二个没有视图的操作,并在相关控制器中返回返回RedirectToAction("Index")。在OrdersItemsController我的行动如下:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MarkedShipped(IEnumerable<orders_items> orderItems)
{
    if (ModelState.IsValid)
    {
        foreach (var item in orderItems)
        {
            unitOfWork.GenericRepository<orders_items>().Update(item);
        }
    }
    return RedirectToAction("Index");
}

在Views中的OrdersItems文件夹中的Index.cshtml中,我所做的如下:

@model IEnumerable<Project.DataAccess.orders_items>
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm("MarkedShipped", "OrdersItems", new { orderItems = Model }))
{

    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.quantity)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.itemprice)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.trackingnumber)
            </th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.quantity)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.itemprice)
                </td>
                <td>
                    @Html.EditorFor(modelItem => item.trackingnumber)
                </td>
                <td>
                    @Html.ActionLink("Edit", "Edit", new { id = item.itemid })
                </td>
            </tr>

        }
    </table>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="MarkShipped" class="btn btn-default" />
        </div>
    </div>
}

我的问题是,我无法从视图中使用orderItems参数获取模型,我不确定这是否是我正在尝试完成的正确“语法”;但是,当调用操作时,orderItems获得的是orders_items的{​​{1}}列表而不是空值。

我还检查了是否存在应用级别异常,但Count = 0

中的Application_Error没有异常

我现在被困了一天所以如果有人能指出我如何将模型(或“编辑过的数据”)传递给我更新数据库的动作,我将非常感激。感谢。

3 个答案:

答案 0 :(得分:1)

在这里试试而不是foreach。

\slN

选中此项: - http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

答案 1 :(得分:1)

首先,您不能将作为集合的模型(或包含属性为复杂对象或集合的模型)添加到表单路径参数中。在内部,帮助程序调用{​​{1}}方法,如果您检查为表单标记生成的html,您将看到类似

的内容
.ToString()

并且绑定将失败,因为您无法将集合绑定到字符串。即使它确实有效,它也会毫无意义,因为它只会回复模型的原始值。

接下来,您无法使用<form action=OrdersItems/MarkedShipped?orderItems=System.Collection.Generic....... 循环来生成表单控件。再次,如果您检查生成的html,您将看到foreach方法生成的输入具有重复的EditorFor()属性(无效的html)和重复的id属性,这些属性没有必要的索引器发布时绑定到集合。您需要使用自定义name的{​​{1}}循环来填充for

使用EditorTemplate循环意味着您的模型必须实现orders_items并且视图需要

for

使用IList<T>,在@model IList<Hochanda.CraftsHobbiesAndArts.DataAccess.orders_items> @using (Html.BeginForm()) // only necessary to add the controller and action if they differ from the GET method { .... @for(int i = 0; i < Model.Count; i++) { @Html.DisplayFor(m => m[i].quantity) .... @Html.EditorFor(m => m[i].trackingnumber) } .... } 中创建部分(注意文件的名称必须与班级名称相匹配)

EditorTemplate

然后在主视图中(您可以使用/Views/Shared/EditorTemplates/orders_items.cshtml

@model Hochanda.CraftsHobbiesAndArts.DataAccess.orders_items
<tr>
  <td>@Html.DisplayFor(m => m.quantity)</td>
  ....
  <td>@Html.EditorFor(m => m.trackingnumber)</td>
  ....
</tr>

IEnumerable<T>方法接受@model IEnumerable<Hochanda.CraftsHobbiesAndArts.DataAccess.orders_items> @using (Html.BeginForm()) { <table class="table"> <thead> .... <thead> <tbody> @Html.EditorFor(m => m) </tbody> </table> .... } ,并根据EditorFor()

中的html为您收藏中的每个项目生成一行

在这两种情况下,你检查html,你现在将看到模型在发布时绑定所需的正确名称属性

IEnumerable<T>

答案 2 :(得分:0)

您可以执行以下操作

 for (int i = 0; i < @ViewBag.Persons; i++)
  {

    <li>
        <table>

            <tr>
                <td>
                    @Html.LabelFor(m => m.Fullname,new { @id = "FullnameLabel" + @i })
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Fullname, new { @id = "Fullname" + @i })
                </td>

            </tr>

通过这种方式,每个html元素都有自己唯一的id,并且可以单独从它们中检索信息。您可以使用for或Foreach。只需确保您的剃刀迭代器正常运行。您可以在源中查看元素ID以查看它是否正常工作。