Asp.net MVC, Html.DropDownList and Selected Value

I recently ran into the altogether common problem of the Html.DropDownList helper rendering a drop down list with no value selected. This is a major problem when editing data as by default, the first value is selected and saving would mean the first value is used.

There have been a few issues resulting in the same error. My issue was that I was setting the Name of the drop down list to be equal to the property on my model. I was using the Entity Framework, and had an Image class with a navigation property called Category. I was using this to render the ddl:

<%= Html.DropDownList("Category", (IEnumerable<SelectListItem>)ViewData["categories"])%>

In my controller, I was setting the ViewData like this:

this.ViewData["categories"] = new SelectList(db.CategorySet.ToList(), "CategoryId", "Title", img.CategoryReference.EntityKey);

Unfortunately, even though I had set the selected value (third parameter to the SelectList constructor), the ddl had no value selected.

The fix was quite simple:

<%= Html.DropDownList("CategoryId", (IEnumerable<SelectListItem>)ViewData["categories"])%>

I just changed the Name of the drop down and handled the assignment in the controller.

The reason behind this problem is that asp.net MVC first looks for a match between the name of the drop down and a property on the model. If there’s a match, the selected value of the SelectList is overridden. Changing the name of the drop down is all it takes to remedy the issue.

 

Hope that helps.

24 Comments

  • Thanks very much. This seems to be the only example any where on the internet where the viewdata is cast to IEnumerable in the markup!

  • Can you show the related code? i.e., CategorySet, CategoryReference, the controller method code?

  • Sorry for the delay in getting back to this..I was setting up my new apartment, and it took a LOT of work.

    The related code is very simple.

    img is an Image (not System.Drawing.Image, just an Entity).
    Each image has a Category. Each category can have one or mor Images.

    I'm using The Entity Framework, and CategorySet is the plural of Category.

    -------------------
    The controller to handle the postback is like this:
    public ActionResult Edit(string ImageId, string Description, int Rating, string CategoryId)
    {
    Guid imageId = new Guid(ImageId);
    var img = db.ImageSet.Where(x => x.ImageId == imageId).First();
    try
    {
    img.Description = Description;
    img.Rating = Rating;

    img.CategoryReference.EntityKey = new System.Data.EntityKey("StudiomorphEntities.CategorySet",
    "CategoryId", new Guid(CategoryId));
    .......
    db.SaveChanges();

  • I was experiencing a similar problem but I was eventually able to get the selected value to show without matching the name of the dropdown to a property of the select list.

    HTML -


    Controller Code -
    ViewData["PropertyStyles"] = new SelectList(_typeRepository.GetPropertyStyles(), "TypeId", "TypeDescription", t);

  • can i get the source code for how to bind dropdownlist from mvc

  • I have tried everything to get my Html.dropdownlist to work, but it's just not working.

    Controller code:

    Function Create() As ActionResult

    Dim allCats = chchtvdc.GetCategories
    ViewData("CategoryID") = New SelectList(allCats, "CategoryID", "CategoryName")


    Dim allDifficulties = chchtvdc.GetDifficulties
    ViewData("Difficulty") = New SelectList(allDifficulties, "DifficultyID", "DifficultyLevel")

    Return View()
    End Function

    HTML:

    Difficulty:





    Category:






    I get the error:

    There is no ViewData item with the key 'DifficultyID' of type 'IEnumerable'.

    Any help will be appreciated.

  • This also works but the main reason of dropdownlist not showing the selected value is that the page is beingposted back whenever a button is clicked and thus the page_load event handler is called which in turn resets the selected value property , so to rectify just check in the page_load handler that wthr it is being posted back or being loaded for the first time , by inserting if page.ispostback = false.

  • Shailja, this is about MVC, not webforms.

  • thanks for your reply

  • Thanks.

    I discovered the same bug. Your fix worked.

    Cheers

  • Puta que pariu! Quero fórum em Português!! Não entendo nada que vcs falam!!!

  • There is one more method of selecting item described in this link to bind dropdownlist.
    http://www.altafkhatri.com/Technical/How_to_bind_IList_with_MVC_Dropdownlist_box

  • This issue was driving me nuts. I was tracing the SelectListItem enumeration and found that the item that I marked as selected was indeed kept selected but it was just not reflecting in the DropDownList. So, as you said, I changed the name of the DropDownList to match the property name on the model, and it worked fine. Thanks for the post. Much appreciated.

  • This really helped! Thanks!

  • Oi Brasileiro, se queresse em portugues, porque nao utilize o google translate?

  • Thanks for the post! It's helpful!

  • how to create dropdownlist

  • Worked great the first time. Saved me lots of time. Thanks!!!

  • Very helpful. Thanks

  • Fixed! thanks :)

  • Thanks you very much.

    I have a simple application for bind categories and it select the value of dropdownlist that, this is for selected product.

    I think this is very easy. no?

    in controller :

    public ActionResult Edit(int id)
    {
    var p = db.ProductSet.First(a => a.ProductId == id);

    ViewData["categories"] = new SelectList(db.CategorySet.ToList(),
    "CategoryId", "CategoryName", p.Category.CategoryId);

    return View(p);
    }

    and in view :




  • Thanks a lot!!! It really help me up, I had a while trying to figure out what was wrong in my code

  • http://www.itpian.com/Coding/how-to-select-the-first-value-of-the-dropdownlist-in-asp-net.aspx

    chk this for more information

  • I wonder whose brilliant idea it was to throw away the list you explicitly give it in favor of something it finds on the Model or ViewData.

Comments have been disabled for this content.