C# 动态复选框-错误:集合为只读
我对MVC4很陌生,我过去使用asp.net的经验一直在使用Webforms,所以我想我需要一些小心的手。提前谢谢你 我正在创建一个简单的web应用程序,类似于选择乐透号码。此时,用户选择他们想要的数字(没有限制,以“1”开头),并将其发布到下一页,在那里我继续对用户选择的数字进行操作。可供选择的数字数量是动态的,并由复选框表示 问题是,提交视图时,我会看到错误页面“Collection is read-only” 模型-LottoNumbers.cs bool[]number用于存储用户已检查的数字C# 动态复选框-错误:集合为只读,c#,asp.net,asp.net-mvc-4,visual-studio-2012,C#,Asp.net,Asp.net Mvc 4,Visual Studio 2012,我对MVC4很陌生,我过去使用asp.net的经验一直在使用Webforms,所以我想我需要一些小心的手。提前谢谢你 我正在创建一个简单的web应用程序,类似于选择乐透号码。此时,用户选择他们想要的数字(没有限制,以“1”开头),并将其发布到下一页,在那里我继续对用户选择的数字进行操作。可供选择的数字数量是动态的,并由复选框表示 问题是,提交视图时,我会看到错误页面“Collection is read-only” 模型-LottoNumbers.cs bool[]number用于存储用户已检查
namespace Lotto.Models
{
public class LottoNumbers
{
public string name { get; set; }
public bool[] numbers { get; set; }
public LottoNumbers() {
numbers = new bool[49];
}
public LottoNumbers(int limit)
{
numbers = new bool[limit];
}
}
}
在HomeController.cs中。。。
我宣布了LottonMembers ln,和
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Lotto.Models;
namespace Lotto.Controllers
{
public class HomeController : Controller
{
public LottoNumbers ln;
public ActionResult Index()
{
return View();
}
public ActionResult SetNumbers()
{
ln = new LottoNumbers(30);
// 30 checkboxes will be generated on the view
return View(ln);
}
[HttpPost]
public ViewResult SetNumbers(LottoNumbers l)
{
// get checkbox values
return View();
}
}
}
查看-SetNumbers.cshtml
@model Lotto.Models.LottoNumbers
@{
ViewBag.Title = "SetNumbers";
}
<h2>SetNumbers</h2>
@using (Html.BeginForm()) {
<div>
@Html.LabelFor(m => m.name)
@Html.EditorFor(m => m.name)
</div>
<div id="numberlist">
@for (int i = 0; i < Model.numbers.Length; i++)
{
<div class="item-number" style="">
@Html.EditorFor(m => m.numbers[i])
<label class="lbl-number" for="numbers[@i]">@(i+1)</label>
</div>
}
</div>
<div style="clear:both;">
<input type="reset" value="Reset everything" />
<input type="submit" value="Submit" />
</div>
}
@model Lotto.Models.LottoNumbers
@{
ViewBag.Title=“SetNumbers”;
}
设定值
@使用(Html.BeginForm()){
@LabelFor(m=>m.name)
@EditorFor(m=>m.name)
@对于(int i=0;im.numbers[i])
@(i+1)
}
}
如果查看“Collection is read only”(集合为只读)错误的堆栈跟踪,可以看到它是在模型绑定期间发生的,即它试图从表单post传回的数据重新创建LottonMembers对象时发生的
之所以会出现错误,是因为您使用接受参数的构造函数使用数组大小初始化对象,但当它发回数据时,它不知道重新创建对象时数组需要的大小
要解决这个问题,最好使用列表,并将大小作为LottoNumbers对象的属性
使用列表意味着您不必预先初始化数组的大小。将大小作为属性意味着您可以将大小嵌入到隐藏的输入变量中,以便将其传递回控制器,并且它应该正确地进行模型绑定。将数组更改为列表
public string Name { get; set; }
public List<bool> Numbers { get; set; }
public LottoNumbers()
{
Numbers = new List<bool>();
for (var i = 0; i < 40; i++)
{
Numbers.Add(false);
}
}
public LottoNumbers(int limit)
{
Numbers = new List<bool>();
for (var i = 0; i < limit; i ++)
{
Numbers.Add(false);
}
}
所以当你的代码到达这里后
@foreach (var numberBool in Model.Numbers)
当模型为空时,它会爆炸。您可以通过多种方式修复此问题,具体取决于您希望应用程序的运行方式。如果您希望用户在提交后看到一个空白的数字列表,只需执行此操作,并在回邮时添加一些成功消息
[HttpPost]
public ViewResult SetNumbers(LottoNumbers l)
{
//process stuff
ln = new LottoNumbers(30);
return View(ln);
}
您还可以简单地将用户重定向回索引页面。无论哪种情况,都会导致错误,因为您没有将带有数字的模型传递回视图 非常感谢您的解释!那我就用清单。如果我有足够的代表,我会投赞成票;我回答得太慢了,但我会投你一票@保宾德:我也会投你一票,因为我正要加上一个例子,但你比我强。。。团队合作!你为我节省了很多时间,因为我需要复习一下如何使用列表。非常感谢。奇怪的是,在提交页面后,@foreach行上出现了一个NullReferenceException。我不明白…添加了一个“空引用异常”部分来解释为什么会出现空引用异常,这也难怪。我已经超越了自己。谢谢你的耐心!现在是另一个问题。。。我找回了在视图中输入的变量名,但是列表显示了所有的假值,即使我选中了一些框。修复了我的问题-我将视图中的foreach更改为for循环,并使用@Html.EditorFor(m=>m.Numbers[index])
@foreach (var numberBool in Model.Numbers)
[HttpPost]
public ViewResult SetNumbers(LottoNumbers l)
{
//process stuff
ln = new LottoNumbers(30);
return View(ln);
}