39
//in controller
ViewBag.Categories = categoryRepository.GetAllCategories().ToList();

//in view
 @Html.DropDownList("Cat", new SelectList(ViewBag.Categories,"ID", "CategoryName"))

How can I make it so that by default it says "-Select Category-"

And validate to check something is selected (client and on the model)

Thanks

4 Answers 4

95

I just can't believe that there are people still using ViewData/ViewBag in ASP.NET MVC 3 instead of having strongly typed views and view models:

public class MyViewModel
{
    [Required]
    public string CategoryId { get; set; }

    public IEnumerable<Category> Categories { get; set; }
}

and in your controller:

public class HomeController: Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Categories = Repository.GetCategories()
        }
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            // there was a validation error =>
            // rebind categories and redisplay view
            model.Categories = Repository.GetCategories();
            return View(model);
        }
        // At this stage the model is OK => do something with the selected category
        return RedirectToAction("Success");
    }
}

and then in your strongly typed view:

@Html.DropDownListFor(
    x => x.CategoryId, 
    new SelectList(Model.Categories, "ID", "CategoryName"), 
    "-- Please select a category --"
)
@Html.ValidationMessageFor(x => x.CategoryId)

Also if you want client side validation don't forget to reference the necessary scripts:

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
Sign up to request clarification or add additional context in comments.

8 Comments

May i know the reason behind supporting Strongly type instead of ViewData/ViewBag especially in Dropdownlist context ?
@wwcdwdcw, because they are strongly typed ensuring compile-time safety and are refactor friendly.
@Html.DropDownListFor(x => x.CategoryId, new SelectList(Model.Categories, "ID", "CategoryName") .. - this is not strongly typed.
I guess a better option would be to define in model as public IEnumerable<SelectListItem> Categories{get;set;} then in your controller populate the Categories with ListedItem then in view just use as @Html.DropDownListFor( x => x.CategoryId, Model.Categories, "-- Please select a category --" )
Please use this method with caution: it does not do server side validation.
|
8

There is an overload with 3 arguments. Html.DropdownList(name, selectList, optionLabel) Update: there was a typo in the below code snippet.

@Html.DropDownList("Cat", new SelectList(ViewBag.Categories,"ID", "CategoryName"), "-Select Category-")

For the validator use

@Html.ValidationMessage("Cat")

1 Comment

There was a type in the code snippet. It should be @Html.DropDownList("Cat", new SelectList(ViewBag.Categories, "ID", "CategoryName"), "-Select Category-")
2

For ListBox / DropDown in MVC5 - i've found this to work for me sofar:

in Model:

[Required(ErrorMessage = "- Select item -")]
 public List<string> SelectedItem { get; set; }
 public List<SelectListItem> AvailableItemsList { get; set; }

in View:

@Html.ListBoxFor(model => model.SelectedItem, Model.AvailableItemsList)
@Html.ValidationMessageFor(model => model.SelectedItem, "", new { @class = "text-danger" })

1 Comment

Why is your SelectedItem a List? But I agree with your example, the "Required" annotation is the key to getting the validation to happen.
0

Example from MVC 4 for dropdownlist validation on Submit using Dataannotation and ViewBag (less line of code)

Models:

namespace Project.Models
{
    public class EmployeeReferral : Person
    {

        public int EmployeeReferralId { get; set; }


        //Company District
        //List                
        [Required(ErrorMessage = "Required.")]
        [Display(Name = "Employee District:")]
        public int? DistrictId { get; set; }

    public virtual District District { get; set; }       
}


namespace Project.Models
{
    public class District
    {
        public int? DistrictId { get; set; }

        [Display(Name = "Employee District:")]
        public string DistrictName { get; set; }
    }
}

EmployeeReferral Controller:

namespace Project.Controllers
{
    public class EmployeeReferralController : Controller
    {
        private ProjDbContext db = new ProjDbContext();

        //
        // GET: /EmployeeReferral/

        public ActionResult Index()
        {
            return View();
        }

 public ActionResult Create()
        {
            ViewBag.Districts = db.Districts;            
            return View();
        }

View:

<td>
                    <div class="editor-label">
                        @Html.LabelFor(model => model.DistrictId, "District")
                    </div>
                </td>
                <td>
                    <div class="editor-field">
                        @*@Html.DropDownList("DistrictId", "----Select ---")*@
                        @Html.DropDownListFor(model => model.DistrictId, new SelectList(ViewBag.Districts, "DistrictId", "DistrictName"), "--- Select ---")
                        @Html.ValidationMessageFor(model => model.DistrictId)                                                
                    </div>
                </td>

Why can't we use ViewBag for populating dropdownlists that can be validated with Annotations. It is less lines of code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.