If the model is a list of objects then @Html.LabelFor model => model[i].member)
creates an empty for
attribute.
The DisplayName works properly, model binding also works just fine. The only thing that does not work is the for
attribute.
Below there are two versions of the MVC code. The first 3 code snippets are for the model, controller and view combination that does not work, (the model is a list). The second set of 3 code snippets work. This time the list is wrapped in an object.
What am I missing?
Model:
public class ViewModel {
public bool ClickMe { get; set; }
}
Controller:
public ActionResult LabelForViewModel() {
List<ViewModel> model = new List<ViewModel>() {
new ViewModel() { ClickMe = true}
};
return View(model);
}
View:
@model List<ModelBinding.Models.ViewModel>
// form code removed for brevity
@for (var i = 0; i < Model.Count; i++) {
<div class="form-group">
@Html.LabelFor(model => model[i].ClickMe)
<div class="col-md-10">
@Html.EditorFor(model => model[i].ClickMe, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model[i].ClickMe, "", new { @class = "text-danger" })
</div>
</div>
}
Markup:
<div class="form-group">
<label for="">ClickMe</label>
<div class="col-md-10">
<input name="[0].ClickMe" class="form-control check-box" type="checkbox" checked="checked" value="true" data-val-required="The ClickMe field is required." data-val="true"><input name="[0].ClickMe" type="hidden" value="false">
<span class="field-validation-valid text-danger" data-valmsg-replace="true" data-valmsg-for="[0].ClickMe"></span>
</div>
</div>
Please notice that the for field is empty and the input has no id field (that one is used in the "for" field).
I have created a wrapper model that contains a list of objects, modified the controller and view and then it works just fine. In this case the "for" field is filled in correctly and everything works as expected.
public class ListWrapper {
public List<ViewModel> ViewModels { get; set; }
}
View:
@for (var i = 0; i < Model.ViewModels.Count; i++) {
<div class="form-group">
@Html.LabelFor(model => model.ViewModels[i].ClickMe)
<div class="col-md-10">
@Html.EditorFor(model => model.ViewModels[i].ClickMe, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ViewModels[i].ClickMe, "", new { @class = "text-danger" })
</div>
</div>
}
Markup:
<div class="form-group">
<label for="ViewModels_0__ClickMe">ClickMe</label>
<div class="col-md-10">
<input name="ViewModels[0].ClickMe" class="form-control check-box" id="ViewModels_0__ClickMe" type="checkbox" checked="checked" value="true" data-val-required="The ClickMe field is required." data-val="true"><input name="ViewModels[0].ClickMe" type="hidden" value="false">
<span class="field-validation-valid text-danger" data-valmsg-replace="true" data-valmsg-for="ViewModels[0].ClickMe"></span>
</div>
</div>
So, it seems that the for
attribute is empty only if the model is a list of objects.
Is this a known issue? Or maybe I'm missing something?