【问题标题】:Working with checkboxes in asp.net mvc3 plus mass update使用 asp.net mvc3 中的复选框以及批量更新
【发布时间】:2012-07-17 09:39:20
【问题描述】:

目前我正在尝试基于一系列复选框创建大规模更新。我似乎找不到使用实体框架的正确方法。

我正在使用带有 MVC3 和 Razor 的 ASP.Net 4。

这是我目前的代码。

查看页面(正常工作)

@model List<LeagueCounters.Models.champion>
<form name="setFree id="setFree" method="POST" action="/Champion/SetFree">
    @foreach (var item in Model)
    {
        if (item.isFree == true)
        {
           <input type="checkbox" id="@item.id" checked="checked" /> @Html.DisplayFor(modelItem => item.displayName)  
        }
        else
        {
            <input type="checkbox" id="@item.id" /> @Html.DisplayFor(modelItem => item.displayName)
        }
    }
<p><input type="submit" value="Save" /></p>

控制器(错误)

[HttpPost, Authorize(Roles = "Admin")]
public ActionResult SetFree(FormCollection fcMain)
{
     var sortedList = from c in _db.champions
                      orderby c.name
                      select c;
     int counter = 0;
     foreach (champion champ in sortedList)
     {
         if (fcMain[counter].Contains("true"))
            champ.isFree = true;
         else
            champ.isFree = false;

         _db.champions.Attach(champ);
         _db.ObjectStateManager.ChangeObjectState(champ, EntityState.Modified);

         counter++;
     }

     _db.SaveChanges();

     return View();
}

错误

索引超出范围。必须是非负数且小于集合的大小。 参数名称:索引

问题

如何正确循环浏览控制器中的复选框?一旦我达到那个点,我的批量更新代码会起作用吗?

提前致谢。

【问题讨论】:

  • 暂时忽略任何其他问题,您的 fcMain[counter] 集合是从 0 开始的,但是您从 1 开始索引/计数器。这意味着您将超过最后一个条目。如果多次使用该站点,假设您的数据收集的长度与复选框的数量相同当然是危险的。
  • 我确实将其更改为零,结果相同。
  • 您是否调试过代码行并查看了多少条目与多少控件?使用未经测试的索引直接索引到 fcMain 是最有可能的失败点。
  • 你能比较一下表单集合的数量和模型集合的数量吗?你在用IE吗

标签: c# asp.net asp.net-mvc-3 entity-framework


【解决方案1】:

这里的问题是只有选中的复选框才会发布到服务器。因此,您不能期望所有复选框键都出现在表单集合中。要解决此问题Html.CheckBoxFor 会创建一个带有复选框的附加隐藏字段,以便可以在服务器端读取结果。我不确定您将如何在这里使用强类型助手,因为您正在循环呈现数据。我想你可以看看这个google search

【讨论】:

    【解决方案2】:

    我认为这条线

    fcMain[counter].Contains("true")
    

    导致错误..您在向视图提供模型时是否使用某种约束选择 (Where)

    你也应该在每个复选框之后添加一个隐藏字段

    <input type="hidden" value="false" id="@item.id" name="@item.id"/>
    

    这样所有的复选框都会提交成功
    您必须拆分值获取服务器端存在的第一个值
    或者您可以跳过两者并直接使用 @Html.Checkbox(item.Id,item.isFree) 这样代码会更干净,无需手动添加额外的 Hidden Input 将由 Razor 引擎自动添加

    您还可以进行一些其他改进来保留代码DRY
    改变这个

    if (item.isFree == true)
    {
       <input type="checkbox" id="@item.id"  checked="checked" /> @Html.DisplayFor(modelItem => item.displayName)  
    }
    else
    {
       <input type="checkbox" id="@item.id" /> @Html.DisplayFor(modelItem => item.displayName)
    }
    

    <input type="checkbox" id="@item.id" name="@item.id" @(!Item.isFree?"checked=\"checked\":\"\"") /> @Html.DisplayFor(modelItem => item.displayName)
    

    我认为你不需要这些

    _db.champions.Attach(champ);
    _db.ObjectStateManager.ChangeObjectState(champ, EntityState.Modified);
    

    【讨论】:

    • 感谢您的改进建议,尽管问题仍然存在:(
    猜你喜欢
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 2012-06-10
    • 1970-01-01
    • 2014-02-03
    相关资源
    最近更新 更多