没有通过Html.BeginForm()将数据从视图传递给Action

本文关键字:视图 数据 Action Html BeginForm | 更新日期: 2023-09-27 18:04:13

我是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");
}

在索引中。在视图的OrdersItems文件夹中的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参数视图中获得模型,我不确定这是否是我想要完成的正确"语法";但是当动作被调用时,我得到的orderItemsCount = 0不是空值的orders_items列表。

我也检查了是否有应用程序级异常,但Global.asax中的Application_Error没有异常

我现在卡住了一天,所以如果有人能告诉我如何将模型(或"编辑的数据")传递给我更新数据库的操作方向,我会非常感激。谢谢。

没有通过Html.BeginForm()将数据从视图传递给Action

首先,你不能将一个集合模型(或者一个包含复杂对象或集合属性的模型)添加到表单路由参数中。内部助手调用.ToString()方法如果你检查为表单标签生成的html你会看到类似

的内容
<form action=OrdersItems/MarkedShipped?orderItems=System.Collection.Generic.......

和绑定将失败,因为集合不能绑定到字符串。即使它可以工作,它也没有意义,因为它只会发回模型的原始值。

接下来,您不能使用foreach循环来生成表单控件。再次,如果您检查生成的html,您将看到EditorFor()方法生成的输入具有重复的id属性(无效的html)和重复的name属性,这些属性在您发布时没有必要的索引器绑定到集合。您需要使用一个for循环或一个自定义的EditorTemplate,用于typeof 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()方法接受IEnumerable<T>,并将根据EditorTemplate

中的html为集合中的每个项目生成一行

在这两种情况下,如果你检查html,你现在会看到正确的名称属性,当你发布

时,你需要绑定模型。
<input type="text" name="[0].trackingnumber" ... />
<input type="text" name="[1].trackingnumber" ... />
<input type="text" name="[3].trackingnumber" ... />

此处用Try For代替foreach。

@for (int i = 0; i < Model.Count; i++)
        {
            <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>
        }

检查这个:- http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

您可以执行以下操作

 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,看看它是否正常工作。