【问题标题】:Model binding to Lists throws "Collection is read-only" exception模型绑定到列表会引发“集合是只读的”异常
【发布时间】:2013-12-05 16:30:26
【问题描述】:

我有这样的课:

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

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

}

在表单发布时可以有可变数量的Items,从零到多。我正在使用 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 =&gt; model.Items[i].Id) 得到的语法基本相同,model.Items 是一个数组而不是一个列表,而且效果很好。这里出了什么问题?

动作方法签名:

public ActionResult Post(SomeModel m)
{

【问题讨论】:

  • 你能显示Action方法签名吗?
  • 哪一行出现错误?
  • @Shyju 在SomeModel() 构造函数被激发出来之后的一段时间(就在它到达Post 之前)。
  • 也显示你的操作方法
  • @Shyju 是[HttpGet] 还是[HttpPost] 一个?无论如何,它在出错之前永远不会到达操作方法。

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


【解决方案1】:

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

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

对我来说,将string[] 替换为List&lt;string&gt; 解决了这个问题。

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

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

【讨论】:

  • 是否有文档支持这背后的原因?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    MVC 模型绑定器应该与数组一起使用,因此用列表替换是一种解决方法,但不是正确的解决方案。

    我也遇到过同样的问题,但只是偶尔会发生。所以我不明白为什么会出现这个问题。然后我发现了一些我认为值得分享的东西:问题出在 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"
        })
    

    -> case B - 无一例外!

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

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

    良好的编码。

    【讨论】:

      【解决方案4】:

      如果一个列表是用IList&lt;string&gt; list = new List&lt;string&gt;(stringArray); 创建的,其中stringArraystring[] 类型,那么它不能被追加,因为它实际上是一个空间有限的数组。如果你使用IList&lt;string&gt; list = new List&lt;string&gt;();,然后使用foreach 将数组的每个元素传输到列表中,那么它将能够扩展。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-12
        • 2012-06-01
        • 2013-06-16
        • 2011-06-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多