在foreach循环中的表单,而不是将模型发布回控制器

时间:2016-09-13 17:32:51

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

我已经四处搜索,无法找到问题的答案。

我有一个接受Foo的视图,如下所示:

@model IEnumerable<MyApplication.Models.Foo>

在视图内部,我有一张桌子。我只是通过foreach模型在一个简单的Foo循环中填充表格。我添加了一个列,用户可以在其中为文本区域中的每一行添加详细信息并保存。

所以视图看起来像这样:

@foreach (var item in Model)
  {
    <tr>
      <th>
           @using (Html.BeginForm("AddDetails", "MyController", FormMethod.Post))
             {
               @Html.AntiForgeryToken()        
               @Html.HiddenFor(u => item.Id)

               @Html.TextAreaFor(u => item.Details, new { @class = "form-control" })                              

               <input type="submit" value="Save" class="btn btn-sm btn-default" />
             }
      </th>
    </tr>
  }

我的控制器设置如下:

    [HttpPost]
    public ActionResult AddDetails(Foo foo)
    { 
    }

当我在该控制器上设置断点foo时,null属性的值始终为Details,而Id始终为0。当它被传递到视图中时,它将所有属性设置为正确,所以我不确定为什么它没有正确回发?

我试过这个:

@using (Html.BeginForm("AddDetails", "MyController", FormMethod.Post, new { foo = Model }))

我还尝试删除foreach循环并更改它以仅将一个模型传递给视图,并且视图仅接受单个模型而不是IEnumerable。当我这样做时,它回复得很好。

这也不起作用。我想知道它是否与我的表单在foreach循环内的事实有关,也许我需要做更多的工作,例如向元素添加data-id属性只需捕获按钮上的click事件并对控制器进行AJAX调用并沿此传递正确的值?

编辑抱歉,我完全忘记了视图模型。这是看起来像:

public class Foo
{
    public int Id { get; set; }

    public string Details { get; set; }
}

2 个答案:

答案 0 :(得分:2)

一般来说,发布到与您的表单视图组成的模型不同的模型是不好的形式。它使很多事情变得困难,其中最重要的是从验证错误中恢复过来。

您在此处执行的操作是循环浏览Foo列表,并创建多个表单,每个表单只提交一个Foo到仅需Foo*For的操作。虽然帖子本身很好,但是在模型上使用Foo帮助器与您发布的模型不同可能不会生成模型绑定器将发布值绑定到其他模型所需的正确输入名称模型。至少,如果由于验证错误需要返回此视图,您将无法保留用户的发布数据,迫使他们完全重复他们的工作。

理想情况下,您应该发布for的完整列表,并且只包含一个包含迭代的表单(在这种情况下,您需要使用foreach而不是Foo) 。或者,您只需列出Foo s,其中包含用于修改特定Foo的链接,您可以在其中只有一个{{1}}的表单。

答案 1 :(得分:0)

尝试这样做。可能的问题

表格应在表格之外 整张桌子的单一表格

将列编辑器包装在tbody而不是thead

@using (Html.BeginForm("AddDetails", "MyController", FormMethod.Post))
{
//thead and tbody
    }