【问题标题】:Update multiple records at once in asp.net mvc在asp.net mvc中一次更新多条记录
【发布时间】:2015-05-22 16:17:42
【问题描述】:

我正在尝试使用asp.net mvc 4EF6 创建一个网站,我想一次更新多行。但由于某种原因,它不起作用,我收到这样的错误,

System.NullReferenceException:对象引用未设置为对象的实例

这是我的代码,

控制器

[HttpPost]
    public ActionResult MakeDue(List<BillCheck> BillLists)
    {
        if (Session["username"] != null)
        {
            if (ModelState.IsValid)
            {
                foreach (var BillId in BillLists)
                {
                    var getDue = db.BillChecks.Where(p => p.id == BillId.id).FirstOrDefault();
                    getDue.due = BillId.due;
                }
                db.SaveChanges();
                return RedirectToAction("Success");
            }
            else
            {
                return RedirectToAction("Failed");
            }
        }
        else
        {
            return RedirectToAction("Login");
        }
    }

查看

@using (Html.BeginForm("MakeDue", "Home"))
{
    @Html.ValidationSummary(true)
    @foreach(var item in Model.DueList)
    {
        @Html.HiddenFor(modelItem => item.id)
        <tr>
            <td>@Html.DisplayFor(modelItem => item.flat)</td>
            <td>@Html.DisplayFor(modelItem => item.name)</td>
            <td>@Html.TextBoxFor(modelItem => item.due)</td>
        </tr>
    }
    <input type="submit" class="btn btn-success" value="Update" />
}

我的代码有问题吗?如何一次更新due 的所有输入?

【问题讨论】:

  • 在你的控制器中发现getDue 可以为空。
  • DueListBillList 长什么样子?
  • 你在哪一行得到异常?
  • NullReferenceException 的几乎所有情况都是相同的。请参阅“What is a NullReferenceException and how do I fix it?”获取一些提示。
  • @JohnSaunders,请仔细阅读我的问题。我有一个与NullReferenceException 高度无关的特定问题。我只想知道一次更新多条记录。您给定的帖子对我来说不是解决方案。所以它不是重复的。

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


【解决方案1】:

您的第一个问题是您使用foreach 循环会生成重复的name 属性,这些属性不会绑定到集合,因此BillLists 参数将始终是一个空集合(它也是生成重复的id 属性,这是无效的 html)。您需要为 typeof BillCheck 使用 for 循环或自定义 EditorTemplate。使用for 循环,您的视图需要是

using (Html.BeginForm("MakeDue", "Home"))
{
  @Html.ValidationSummary(true)
  @for(int i = 0; i < Model.DueList.Count; i++)
  {
    
    <tr>
      <td>
        @Html.HiddenFor(m => m.DueList[i].id)
        @Html.DisplayFor(m => m.DueList[i].flat)</td>
      <td>@Html.DisplayFor(m => m.DueList[i].name)</td>
      <td>@Html.TextBoxFor(m => m.DueList[i].due)</td>
    </tr>
  }
  <input type="submit" class="btn btn-success" value="Update" />
}

另请注意,@Html.HiddenFor() 帮助器必须位于 &lt;td&gt; 元素内才能成为有效的 html。

下一个问题是视图中的模型不是typeofList&lt;BillCheck&gt;,但它确实包含一个名为DueList的属性,即typeofList&lt;BillCheck&gt;所以你的POST方法需要是

public ActionResult MakeDue(YourModel model)

其中YourModel 是您用于生成视图的类名(即在@model ??? 语句中)。然后你在控制器中循环需要的方法是

foreach (var BillId in model.DueList)
{
  var getDue = db.BillChecks.Where(p => p.id == BillId.id).FirstOrDefault();
  if (getDue != null) // add this
  {
    getDue.due = BillId.due;
  }
}
db.SaveChanges();

还要注意添加了if (getDue != null) 检查。

旁注:您正在检查if (ModelState.IsValid)。如果ModelState 无效,建议您返回视图,以便用户更正任何错误。

【讨论】:

  • 这个例子,以及随之而来的解释,做了一些可悲的是很少有教程没有做过的事情——强调你必须使用 for 循环(而不是 foreach)并给出明确的生成的 html-list 中每个元素的索引,以便控制器正确拾取它。真的很棒!
  • 另外值得注意的是,@Html.DisplayFor 不会将其值发布到控制器。您还需要为要发布的值使用 Html.HiddenFor stackoverflow.com/questions/12314849/…
  • 正如我所提到的,此解决方案也适用于 HTML 标记的另一种类型 - 例如 &lt;div class=row&gt; 而不是 tr&lt;div class=col-&gt; 而不是 td
  • 我在将它移植到 .net 核心时遇到问题 - 有人在 dotnet 核心下得到这个工作吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 2015-01-13
  • 2020-12-11
  • 2011-02-14
  • 1970-01-01
相关资源
最近更新 更多