I have three dropdownlistfor in a loop that do not show the correct value from the DB. They always default to the first entry. I have checked and double checked the DB and verified that it should be the second one in the list. The list is also created correctly. What am I missing?
@foreach (CustomerMeasurementProfile oProfile in Model.Customer.CustomerMeasurementProfiles.Where(m => m.DeletedDate == null))
{
<div class="valuesforoneprofile form-group form-group-tight col-md-2">
<div class="col-md-11" >
@Html.Hidden(string.Format("Customer.CustomerMeasurementProfiles[{0}].Id", i), oProfile.Id)
@Html.Hidden(string.Format("Customer.CustomerMeasurementProfiles[{0}].CustomerId", i), oProfile.CustomerId)
@Html.TextBox(string.Format("Customer.CustomerMeasurementProfiles[{0}].Name", i), oProfile.Name, new { @class = "form-control input-sm" })
</div>
<div class="col-md-11" style="text-align:center">
@Html.CheckBox(string.Format("DeleteProfiles[{0}]", i), Model.DeleteProfiles[i])
</div>
<div class="col-md-11" style="padding-top:4px;">
@Html.DropDownListFor(m => oProfile.BodyTypeShoulderId, new SelectList(Model.BodyTypeShoulders, "Id", "Name"), new { @class = "form-control input-sm-select" })
</div>
<div class="col-md-11" style="padding-top:4px;">
@Html.DropDownListFor(m => oProfile.BodyTypePostureId, new SelectList(Model.BodyTypePosture, "Id", "Name"), new { @class = "form-control input-sm-select" })
</div>
<div class="col-md-11" style="padding-top:4px;">
@Html.DropDownListFor(m => oProfile.BodyTypeChestId, new SelectList(Model.BodyTypeChest, "Id", "Name"), new { @class = "form-control input-sm-select" })
</div>
If you want to set the selected value that is coming in Model. You need to do it like this:
The above code will set the dropdown selected value to whatever is in the current Model object
BodyTypeShoulderId
The first argument of
DropDownListFor
tells that on form post drop down selected value will be mapped with the Model property which is set there (we are passingm => oProfile.BodyTypeShoulderId
) but this not sets selected Value.For setting selected value you have to pass
SelectList
fourth parameter using this overload of SelectList class which isobject selectedValue
Unfortunately
@Html.DropDownListFor()
behaves a little differently than other helpers when rendering controls in a loop. For a single objectwould work fine (if the value of
BodyTypeShoulderId
matches the value of one of the options, then that option would be selected). Ehsan has shown a work around when using it in a loop, however you have a few other issues in you code, not the least is that many of your properties will not post back correctly to a collection because your using aforeach
loop rather than afor
loop (which is generating duplicatename
andid
attributes). Your also generating a newSelectList
in each iteration of the loop which is not very efficient.You can solve both these and the dropdown selection issue by using an
EditorTemplate
. Assuming propertyCustomerMeasurementProfiles
is typeofCustomerMeasurementProfiles
, thenCustomerMeasurementProfiles.cshtml (add this to
Views/Shared/EditorTemplates
orViews/YourController/EditorTemplates
)In the view model, add properties for the
SelectList
's and filtered collection of the items to displayand assign those values in the controller
Then in the main view
Using
@Html.EditorFor()
with a collection will correctly name the controls (and correctly select the right options) and on post back,ActiveCustomerMeasurementProfiles
will now be correctly populated with all its properties.