Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collection is readonly on array in ViewModel

Tags:

c#

asp.net-mvc

I have an MVC ViewModel that looks like this:

public class FruitBoxViewModel {

    public FruitBoxViewModel()
    {
        BoxLabels = new BoxLabelViewModel[3];
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public BoxLabelViewModel[] BoxLabels {get; set; }
}

A commented requested to see what the BoxLabelViewModel looks like, here it is:

public class BoxLabelViewModel {
    public string SkuCode {get; set;}
    public int? ProductionNumber { get; set; }
}

Each FruitBox can have between 1 and 3 BoxLabels, no more, no less. To enforce, this, I thought I'd use an Array instead of a List.

I have a for loop in my Razor view that handles my inputs on the page:

@for(var i = 0; i < 3; i++ )
{
  @Html.LabelFor(model => Model.BoxLabels[i].SkuCode)
  @Html.EditorFor(m => Model.BoxLabels[i].SkuCode, new { htmlAttributes = new { @class = "form-control" } })
}

When I submit the form, I get the yellow screen of death (YSOD) with the error:

Collection is read-only.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NotSupportedException: Collection is read-only.

Is there a rule I don't know about that says you should never use an Array in your ViewModels or something?

like image 786
J86 Avatar asked Nov 02 '25 00:11

J86


1 Answers

This is one of the 'got you' cases of using array instead of list. Model binder will not create new instance of an array because you have provided one in constructor. Then it will use it as IList instance and try to invoke Insert or Add and such calls will fail for array and succeed for list.

Just remove the assignment form constructor or use list in your model and write some JS to validate your form before sending post request. Then validate count of items on server side.

like image 69
Rafal Avatar answered Nov 03 '25 17:11

Rafal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!