1

I'm trying to generate element names using Html.NameFor<> method, here's my code:

@foreach (var category in Model.Categories)
{
  <input type="hidden" name="@Html.NameFor(m=> category.CategoryId)" 
    value="@category.CategoryId" />
}

The generated item's name get this value: category.CategoryId, instead of Categories[i].CategoryId (where i refers to the current indexer).

Why isn't it working?

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632

3 Answers3

3

in short, use a for loop instead of a foreach loop (see the answer here). You need to manually index it

MVC Razor view nested foreach's model

EDIT: added sample code

@for(int i=0; i < Model.ListTwo.Count; i++) 
{
    @Html.HiddenFor(t => t.ListTwo[i].Id)
}

Okay, for collections that inherit from ICollection, try

@for (int i = 0; i < Model.CollectionThree.Count; i++) 
{
   @Html.Hidden("CollectionThree[" + i + "].Id", Model.CollectionThree.ElementAt(i).Id)
}

Another edit: To avoid using the property name, you could do something like

@for (int i = 0; i < Model.CollectionThree.Count; i++)
{
   @Html.Hidden(Html.NameFor(t => Model.CollectionThree) + "[" + i + "]." +
                Html.NameFor(t =>Model.CollectionThree.ElementAt(i).Id)
               ,Model.CollectionThree.ElementAt(i).Id )
}

Its inelegant, but it doesn't hardcode the property name.

And then lets take those guys out of the loop

 @{
   var collectionname = Html.NameFor(t => Model.CollectionThree);
   var propname = Html.NameFor(t => Model.CollectionThree.First().Id);
  }

@for (int i = 0; i < Model.CollectionThree.Count; i++)
 {
      @Html.Hidden( collectionname+ "[" + i + "]." + propname ,Model.CollectionThree.ElementAt(i).Id )
 }

My apologies for not responding earlier. I logged out as I had other things to do. You also may want to do a null check ie, if count > 0, then assign the propname, otherwise skip the whole thing

Community
  • 1
  • 1
monkeyhouse
  • 2,875
  • 3
  • 27
  • 42
  • In my scenario, index accessors are invalid, the `Categories` property is of `ICollection`, that doesn't support an indexer. Are there any other solutions? – Shimmy Weitzhandler Jun 08 '13 at 23:36
  • Actually my solution is missing the property name, any assistant will be appreciated. Even splitting it up in few fields, but no hard-coding property names. – Shimmy Weitzhandler Jun 09 '13 at 00:19
1

According to user1778606's answer, I will use the prop. name and indexer separately, like this:

@{
 var modelName = Html.NameFor(m => m.Categories);
 var catIndex = 0;   
}

@foreach (var category in Model.Categories)
{ 
 <input type="hidden" class="checkbox"
   name="@string.Format("{0}[{1}]", modelName, catIndex++)"
   value="@category.CategoryId" />      
}
Community
  • 1
  • 1
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
0

Use @Html.HiddenFor and pass in the array indexed expression for CategoryId

@for(int i=0; i < Model.Categories.Count; i++)
{
    @Html.HiddenFor(m => Model.Categories[i].CategoryId)
}
Aaron Hudon
  • 5,280
  • 4
  • 53
  • 60