snaksa
snaksa

Reputation: 577

ASP.NET MVC Binding array to DropDownFor

I have an array that i want to bind to a dropdown. Here is the code:

@for (int i = 1; i <= 5; i++)
{
    @for (int j = 1; j <= 7; j++)
    {
        @Html.DropDownListFor(m => @Model.Periods, new SelectList(@Model.Items, "Id", "Title", @Model.ScheduleList[i, j]))
    }
}

@Model.Periods is an ordinary empty integer array. @Model.ScheduleList is a two dimensional integer array and holds the values of the option that should be selected on binding. If I replace:

@Model.Periods

with:

@Model.Periods[i*10 + j]

The selected values are being shown but the generated select input has name like for example Periods[34], not just Periods and I get null in my view model on postback. So my question is: How can I bind an oridnary array to dropdown and pass it the selected value with another array?

Upvotes: 0

Views: 370

Answers (1)

Red
Red

Reputation: 2776

@Model.Periods[i*10 + j] is not 100% correct - to post that data to your COntroller you have to post it back with all values starting from Periods[0] straight to Periods[5 * 7 - 1].

If any of Periods[X] (where X is from 0 to 34 included) will be missing, you won't receive correct data. Also index of array should strictly start from 0.

So for example:

Periods[0] = 1
Periods[1] = 2
Periods[2] = 3
Periods[4] = 4

Will be bound to following array: [1, 2, 3], because there's no payload item with sequential index between 2 and 4.

For payload:

Periods[1] = 1
Periods[2] = 2
Periods[3] = 3
Periods[4] = 4

Result will be null - first index of the array is missing in the payload.

So for you probably @Model.Periods[(i-1)*10 + (j-1)] should be fine.

If you really need your indexes be non-sequential, you can use this work-around: for each element add hidden field:

<input type="hidden" name="Periods.Index" value="{your index}" />

So your code will look this way:

@for (int i = 1; i <= 5; i++)
{
    @for (int j = 1; j <= 7; j++)
    {
        <input type="hidden" name="Periods.Index" value="@(i * j)" /> 
        @Html.DropDownListFor(m => @Model.Periods, new SelectList(@Model.Items, "Id", "Title", @Model.ScheduleList[i, j]))
    }
}

But this is not to be used in your current scenario. More info on indexers can be found in the web - for ex. on http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

Upvotes: 1

Related Questions