0

I'm trying list items in my MVC view, following this example: Model Binding to a List. I'm using MVC 5. There example says to do this:

<%@ Page Inherits="ViewPage<IList<Book>>" %>
<% for (int i = 0; i < 3; i++) { %>
    <%: Html.EditorFor(m => m[i]) %>
<% } %>

I'm trying to do this:

for (int i = 0; i < Model.SubmissionTypesSelected.Count(); i++)
{
    Html.EditorFor(m => m.SubmissionTypesSelected[i]);
}

SubmissionTypesSelected is defined like this:

public ICollection<PTSubTypeSelected> SubmissionTypesSelected { get; set; }

I get this message:

Cannot apply indexing to an expression of type 'System.Collections.Generic.ICollection'

M Kenyon II
  • 4,136
  • 4
  • 46
  • 94
  • 4
    Why don't you use a `foreach` instead? – Yacoub Massad Apr 25 '16 at 20:45
  • 5
    In the example, you have `IList`. In your code there's `ICollection`. That's not the same. IList is indexable. ICollection is not. Also, what Yacoub said. Iterating 0..Count === foreach, and ICollection is "foreachable" (just as every IEnumerable is) – quetzalcoatl Apr 25 '16 at 20:45
  • This is part of a larger issue. I have nested collections, and can't get the results from the inner most collection. I was trying to use the index method to see if I could fix the problem. – M Kenyon II Apr 25 '16 at 20:51
  • See also: http://stackoverflow.com/questions/36850921/how-to-handle-nested-collections-in-mvc-5 – M Kenyon II Apr 25 '16 at 20:57
  • 1
    `ICollection` implements `IEnumerable`, so you have access to its `ToArray()` method if you absolutely need to use indexing. But `foreach` is the better approach normally. – Michael Blackburn Apr 25 '16 at 20:59

3 Answers3

1

The error is kind of self-explanatory; you can't use indexing on an ICollection{T} because it is designed to be able to modify the contents of a collection of elements, not the order of them. Changing it to a IList{T} is a simple answer, as the example you've linked does.

MVC needs to have indexes added in HTML so it can figure out which property value goes with which item in a collection on postback. The EditorFor will do this for you if you pass it an IEnumerable of any kind directly. So you can just do this:

Html.EditorFor(m => m.SubmissionTypesSelected);

It will loop through each item, generate an index for you, and pass the individual item to your editor template.

Will Ray
  • 10,621
  • 3
  • 46
  • 61
0

What happens if you do this:

var typesArray = Model.SubmissionTypesSelected.ToArray();
for (int i = 0; i < typesArray.Length; i++)
{
    Html.EditorFor(m => typesArray[i]);
}
Michael Blackburn
  • 3,161
  • 1
  • 25
  • 18
0

Try using CopyTo(Array, Int32) and then continue to iterate as you would normally do with an array.

Daniel Arechiga
  • 847
  • 7
  • 19