Inside model I have data annotations:
[Required(ErrorMessageResourceName = "SelectCategory", ErrorMessageResourceType = typeof(MyProject.Properties.Resources)), Range(1, int.MaxValue, ErrorMessageResourceName = "SelectCategory", ErrorMessageResourceType = typeof(MyProject.Properties.Resources))]
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
and two situations:
Situation1
Inside controller I have
List<Category> categories = db.GetCategories();
ViewBag.CategoryId = categories;
Inside View:
<div class="form-group">
@Html.LabelFor(model => model.CategoryId, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-6">
@Html.DropDownListFor(model => model.CategoryId, new SelectList(ViewBag.CategoryId, "Id", "Name", 2), htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.CategoryId, "", new { @class = "text-danger" })
</div>
</div>
Html result:
<div class="form-group">
<label class="control-label col-md-3" for="CategoryId">Category</label>
<div class="col-md-6">
<select class="form-control" data-val="true" data-val-number="The field Category must be a number." data-val-range="Select category" data-val-range-max="2147483647" data-val-range-min="1" data-val-required="Select category" id="CategoryId" name="CategoryId">
<option value="0">---Select---</option>
<option value="1">Cat1</option>
<option value="2">Cat2</option>
<option value="3">Cat3</option>
</select>
<span class="field-validation-valid text-danger" data-valmsg-for="CategoryId" data-valmsg-replace="true"></span>
</div>
</div>
I have validation attributes inside 'select' element, but no selected element
Situation2:
Inside controller I have
List<Category> categories = db.GetCategories();
ViewBag.CategoryId = new SelectList(categories, "Id", "Name", 2);
Inside View:
<div class="form-group">
@Html.LabelFor(model => model.CategoryId, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-6">
@Html.DropDownList("CategoryId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.CategoryId, "", new { @class = "text-danger" })
</div>
</div>
Html result:
<div class="form-group">
<label class="control-label col-md-3" for="CategoryId">Category</label>
<div class="col-md-6">
<select class="form-control" id="CategoryId" name="CategoryId">
<option value="0">---Select---</option>
<option value="1">Cat1</option>
<option selected="selected" value="2">Cat2</option>
<option value="3">Cat3</option>
</select>
<span class="field-validation-valid text-danger" data-valmsg-for="CategoryId" data-valmsg-replace="true"></span>
</div>
</div>
I have no validation attributes inside 'select' element, but I have selected element
Could anyone explain me what is wrong? What should I do to have validation attributes and selected option?
Firstly, you cannot use the same name for the ViewBag
property as your model property. Change the ViewBag
property to (say) ViewBag.CategoryList
Secondly you categories
appears to contain an item with ID=0
and Name="Select"
so all your options have a value (zero is an integer so its valid) and you will never get an error message. Remove that item from categories
and use
@Html.DropDownListFor(m => m.CategoryId, new SelectList(ViewBag.CategoryList, "Id", "Name"), "--Select--", new { @class = "form-control" })
This will render
<select class="form-control" data-val="true" data-val-number="The field Category must be a number." data-val-range="Select category" data-val-range-max="2147483647" data-val-range-min="1" data-val-required="Select category" id="CategoryId" name="CategoryId">
<option value>---Select---</option>
<option value="1">Cat1</option>
<option value="2">Cat2</option>
<option value="3">Cat3</option>
</select>
Note the first option has no value, so if this one is selected, the Required
validation error will be displayed.
Finally, to set the selected item when the page is first rendered, assign it to the property in the controller before you pass the view
model.CategoryId = 2;
return View(model);
and the the 3rd option("Cat2") will be selected by default.