90

I'm using the DropDownListFor helper method inside of an edit page and I'm not having any luck getting it to select the value that I specify. I noticed a similar question on Stackoverflow. The suggested workaround was to, "populate your SelectList in the view code". The problem is that I've already tried this and it's still not working.

<%= Html.DropDownListFor(model => model.States, new SelectList(Model.States.OrderBy(s => s.StateAbbr), "StateAbbr", "StateName", Model.AddressStateAbbr), "-- Select State --")%>

I have set a breakpoint and have verified the existence (and validity) of model.AddressStateAbbr. I'm just not sure what I'm missing.

Community
  • 1
  • 1
senfo
  • 28,488
  • 15
  • 76
  • 106

11 Answers11

197

After researching for an hour, I found the problem that is causing the selected to not get set to DropDownListFor. The reason is you are using ViewBag's name the same as the model's property.

Example

public  class employee_insignia
{ 
   public int id{get;set;}
   public string name{get;set;}
   public int insignia{get;set;}//This property will store insignia id
}

// If your ViewBag's name same as your property name 
  ViewBag.Insignia = new SelectList(db.MtInsignia.AsEnumerable(), "id", "description", 1);

View

 @Html.DropDownListFor(model => model.insignia, (SelectList)ViewBag.Insignia, "Please select value")

The selected option will not set to dropdownlist, BUT When you change ViewBag's name to different name the selected option will show correct.

Example

ViewBag.InsigniaList = new SelectList(db.MtInsignia.AsEnumerable(), "id", "description", 1);

View

 @Html.DropDownListFor(model => model.insignia, (SelectList)ViewBag.InsigniaList , "Please select value")
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
wut-excel
  • 2,287
  • 1
  • 15
  • 17
  • 36
    This is actually a correct answer!!! To everyone googling, make sure you don't name the ViewBag property the same as the model property! I did not expect this to matter at all, but it actually fixed it. I'm shocked. – Tesserex Nov 12 '12 at 21:24
  • 12
    I have the same problem, even though the ViewBag property has a different name to the model property: `@Html.DropDownListFor(model => model.Title, (SelectList)ViewBag.Salutation, Resources.Labels.Unknown )` – Paul Taylor Nov 28 '12 at 11:38
  • This problem even happens for a different multi select drop down list which uses a SelectList from the ViewBag as a data source!! So if you are having problems with any select lists/multiselect lists then definitely check that this isn't your problem! eg. model.DepartmentsSelectList = new MultiSelectList((SelectList)ViewBag.Departments, "Value", "Text", selectedDepartments); where model.Departments exists. – Stuntbeaver Feb 25 '13 at 18:35
  • 9
    Does anyone know the reason why they can't be the same? This answer saved my laptop from being smashed :) – Jeandre Pentz Sep 30 '13 at 08:46
  • 3
    For the record, if you forget to use a property signature (without get;set; , making it a member but public ) then the dropdown item won't be selected either. Just lost 4 hours on this – MichaelD Jan 19 '14 at 08:01
  • 1
    This is true for `ViewData` also. Do not name the index same. – th1rdey3 Feb 01 '14 at 12:53
  • 7
    I don't understand. I'm having this issue also and we're not using ViewBag. Also the question wasn't using ViewBag – George Mauer Jul 18 '14 at 20:23
  • I wrapped my offending view model property 'Title' in another property called 'TitleDropDownListForBug'. #selfdocumentingcode – Ian Warburton Apr 25 '15 at 17:11
  • 3
    I consider this an ASP.NET MVC bug! – Néstor Sánchez A. Mar 17 '16 at 21:59
  • I am not sure why this is the problem, I wish that I did. Naming them differently fixed some of my issues but I also found out that trailing spaces can cause this issue as well. Edit:Spelling – Error-404-UserNotFound Jul 08 '16 at 16:12
  • I was having the same problem, In my case none of model properties' name was matching but name I was using was matching a model that I was not using for this controller/razor page, so strongly recommended use different name for ViewBag.ListObject in any case. Question was asked long ago but still this bug is there, even there are no warnings. – sairfan Aug 23 '16 at 19:55
  • Actually, it appears that the dropdown name can be the same as the property name, but you have to leave the second parameter = null. E.g.: @Html.DropDownListFor(model => model.Insignia, null, "Please select value") – Gullbyrd Feb 07 '18 at 14:05
35

If you're doing it properly and using a model--unlike all these ViewBag weirdos--and still seeing the issue, it's because @Html.DropDownListFor(m => m.MyValue, @Model.MyOptions) can't match MyValue with the choices it has in MyOptions. The two potential reasons for that are:

  1. MyValue is null. You haven't set it in your ViewModel. Making one of MyOptions have a Selected=true won't solve this.
  2. More subtly, the type of MyValue is different than the types in MyOptions. So like, if MyValue is (int) 1, but your MyOptions are a list of padded strings {"01", "02", "03", ...}, it's obviously not going to select anything.
Chad Hedgcock
  • 11,125
  • 3
  • 36
  • 44
  • 6
    Thank you so much for this answer. I also don't understand why everyone is using ViewBag instead of creating a proper view model. This answer was staring me in the face and I appreciate you connecting the dots. – Ambiguities Mar 26 '17 at 04:01
  • 2
    #2 here is my issue. I have a model property that is a delegate type with a custom model binder to take in the name of the Method and actually bind that method from a list of predefined method calls that match the delegate signature. Has anyone found a was to work around #2 and make it select correctly without some hacky clients side script? – mikeschuld Jun 21 '17 at 23:24
  • 1
    Also, to anyone who has a SelectList with a different value attribute than the display text between the option tags for example: ``. It looks to be actually trying to match the view model property with the display text and not the value attribute to choose the selected option. This had me going for a while. – Jason Hanson Dec 20 '17 at 05:59
  • Because it seems a bit overboard to have to change a model just to contain a simple list of items that you want to contain in a dropdown – LarryBud Apr 29 '21 at 18:55
  • ViewBag is dynamic, so you move any potential type-safety issues from the compile time--where they're easy to see--out into the runtime, where they're much harder to nab (as is the case in your last question to s.o.) – Chad Hedgcock May 04 '21 at 21:59
32

Try:

<%= Html.DropDownListFor(
    model => model.AddressStateAbbr,
    new SelectList(
        Model.States.OrderBy(s => s.StateAbbr),
        "StateAbbr",
        "StateName",
        Model.AddressStateAbbr), "-- Select State --")%>

or in Razor syntax:

@Html.DropDownListFor(
    model => model.AddressStateAbbr,
    new SelectList(
        Model.States.OrderBy(s => s.StateAbbr),
        "StateAbbr",
        "StateName",
        Model.AddressStateAbbr), "-- Select State --")

The expression based helpers don't seem to respect the Selected property of the SelectListItems in your SelectList.

Arseni Mourzenko
  • 50,338
  • 35
  • 112
  • 199
BnWasteland
  • 2,109
  • 1
  • 18
  • 14
18

While not addressing this question - it may help future googlers if they followed my thought path:

I wanted a multiple select and this attribute hack on DropDownListFor wasn't auto selecting

Html.DropDownListFor(m => m.TrainingLevelSelected, Model.TrainingLevelSelectListItems, new {multiple= "multiple" })

instead I should have been using ListBoxFor which made everything work

Html.ListBoxFor(m => m.TrainingLevelSelected, Model.TrainingLevelSelectListItems)
fiat
  • 15,501
  • 9
  • 81
  • 103
1

I also having similar issue and I solve it by as follows, set the

model.States property on your controller to what you need to be selected

model.States="California"

and then you will get "California" as default value.

Prageeth godage
  • 4,054
  • 3
  • 29
  • 45
1

I encountered this issue recently. It drove me mad for about an hour. In my case, I wasn't using a ViewBag variable with the same name as the model property.

After tracing source control changes, the issue turned out to be that my action had an argument with the same name as the model property:

public ActionResult SomeAction(string someName)
{
    var model = new SomeModel();
    model.SomeNames = GetSomeList();
    //Notice how the model property name matches the action name
    model.someName = someName; 
}

In the view:

@Html.DropDownListFor(model => model.someName, Model.SomeNames)

I simply changed the action's argument to some other name and it started working again:

public ActionResult SomeAction(string someOtherName)
{
    //....
}

I suppose one could also change the model's property name but in my case, the argument name is meaningless so...

Hopefully this answer saves someone else the trouble.

JuanR
  • 7,405
  • 1
  • 19
  • 30
1

I know this is an old question but I have been having the same issue in 2020.

It turns out the issue was with the model property being called "Title", I renamed it to "GivenTitle" and it now works as expected.

From

Html.DropDownListFor(m => m.Title, Model.Titles, "Please Select", new { @class = "form-control" })

to

Html.DropDownListFor(m => m.GivenTitle, Model.GivenTitles, "Please Select", new { @class = "form-control" })
Simon
  • 6,062
  • 13
  • 60
  • 97
  • Tried all solutions above and didn't work and this solved it! Seems like "Title" is some special word! – Supun Apr 19 '22 at 16:28
0

One other thing to check if it's not all your own code, is to make sure there's not a javascript function changing the value on page load. After hours of banging my head against a wall reading through all these solutions, I discovered this is what was happening with me.

BMills
  • 881
  • 1
  • 10
  • 24
0

The issue at least for me was tied to the IEnumerable<T>.

Basically what happened was that the view and the model did not have the same reference for the same property.

If you do this

IEnumerable<CoolName> CoolNames {get;set;} = GetData().Select(x => new CoolName{...});}

Then bind this using the

@Html.DropDownListFor(model => model.Id, Model.CoolNames)

The View loses track of the CoolNames property, a simple fix is just to add .ToList() After dooing a projection (.Select()) ;).

jNi
  • 1
  • 1
0

I had the same problem. In the example below The variable ViewData["DATA_ACREDITO_MODELO_INTEGRADO"] has a SelectListItem list with a default selected value but such attribute is not reflected visually.

// data 
        var p_estadoAcreditacion = "NO";
        var estadoAcreditacion = new List<SelectListItem>();
        estadoAcreditacion.Add(new SelectListItem { Text = "(SELECCIONE)"    , Value = " "    });
        estadoAcreditacion.Add(new SelectListItem { Text = "SI"              , Value = "SI"   });
        estadoAcreditacion.Add(new SelectListItem { Text = "NO"              , Value = "NO"   });

        if (!string.IsNullOrEmpty(p_estadoAcreditacion))
        {
            estadoAcreditacion.First(x => x.Value == p_estadoAcreditacion.Trim()).Selected = true;
        }
         ViewData["DATA_ACREDITO_MODELO_INTEGRADO"] = estadoAcreditacion;

I solved it by making the first argument of DropdownList, different to the id attribute.

// error:
@Html.DropDownList("SELECT__ACREDITO_MODELO_INTEGRADO"
, ViewData["DATA_ACREDITO_MODELO_INTEGRADO"] as List<SelectListItem>
, new
{
id         = "SELECT__ACREDITO_MODELO_INTEGRADO"
...
// solved :
@Html.DropDownList("DROPDOWNLIST_ACREDITO_MODELO_INTEGRADO"
, ViewData["DATA_ACREDITO_MODELO_INTEGRADO"] as List<SelectListItem>
, new
{
id         = "SELECT__ACREDITO_MODELO_INTEGRADO"

...

-1

this problem is common. change viewbag property name to other then model variable name used on page.