模型绑定到Lists会抛出“Collection is read-only”异常

时间:2013-12-05 16:30:27

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

我有一个这样的课程:

public class SomeModel
{
    public List<Item> Items { get; set; }

    public SomeModel()
    {
        this.Items = new List<Item>();
    }

}

在表格发布时可能存在可变数量的Item s,零到多。我正在使用javascript在提交时动态附加隐藏的输入字段:

$("#container").children(".item").each(function (i) {
    form.append('<input type="hidden" name="Items[' + i + '].Id" value="' + $(this).val() + '" />');
});

但是,提交后,我收到此错误:

System.NotSupportedException: Collection is read-only.

渲染的语法基本上与@Html.HiddenFor(model => model.Items[i].Id)使用model.Items作为数组而不是列表的语法相同,并且工作正常。这里出了什么问题?

行动方法签名:

public ActionResult Post(SomeModel m)
{

4 个答案:

答案 0 :(得分:16)

您的数组可能正在处理插入(创建新对象的位置)。

当您尝试更新模型时会出现此问题。

对我来说,将string[]替换为List<string>可以解决问题。

//instead of....
public string[] TagsArray { get; set; }

//I now have
public List<string> TagsArray { get; set; }

答案 1 :(得分:0)

我不确定为什么数组之前有效,但显然,这就是导致问题的原因 - 而不是列表。当我将该数组更改为List时,我不再收到错误。应该提到我的模型中仍然有阵列,抱歉。

答案 2 :(得分:0)

如果列表是IList<string> list = new List<string>(stringArray);stringArray类型为string[],则无法附加,因为它实际上是一个空间有限的数组。如果您使用IList<string> list = new List<string>();创建它,然后使用foreach将数组中的每个元素传输到列表中,那么它将能够扩展。

答案 3 :(得分:0)

MVC Model Binder 应该处理数组,所以用 List 替换是一种解决方法,但不是正确的解决方案。

我遇到了同样的问题,但只是偶尔发生在我身上。所以我不明白为什么会出现这个问题。然后我发现了一些我认为值得分享的东西:问题出在 javascript 代码中

这是我的场景:

我有一个模型,我使用一个数组

public class SomeModel
{
    public Item[] Items { get; set; }

    public SomeModel()
    {
        this.Items = new Item[3] {0, 0, 0};
    }
}

我找到了解决方案,只需更改我用来调用 Web 方法的 javascript!

-> case A - 它抛出异常“Collection is read only”

$.ajax({
        type: "POST",
        async: true,
        url: myUrl,
        data: JSON.stringify(myData),
        contentType: "application/json; charset=utf-8",
        dataType: "html"
    })

-> 情况 B - 它毫无例外地工作!

$.ajax({
        type: "POST",
        async: true,
        url: myUrl,
        data: myData,
        dataType: "html"
    })

实际上 MVC 模型绑定应该适用于数组,所以用 List 替换并不是我想要的答案。

良好的编码。