Skip to content

Unexpected Behaviour with ASP.NET MVC SelectList SelectedValue

Well I’ll be darned.

I just spent half an hour today debugging what I thought was a strange oddity today with an ASP.NET MVC Html.DropDownList(), specifically within it’s SelectList element on a simple “add / edit” detail screen on an ASP.NET MVC web form.

I had this code:

[sourcecode language='html']
<%= Html.DropDownList("ModuleMessageType.ModuleID", new SelectList(ViewData.Model.Modules, "ID", "Name", ViewData.Model.FormType == AppHelper.FormType.Add && ViewData.Model.ModuleMessageType.ModuleID == 0 ? Request["moduleid"].ToInt() : ViewData.Model.ModuleMessageType.ModuleID), "-- Select --", new { tabindex = 2, title = "Modules" })%>

Basically stating that when launching the page in "Add" mode, you should select the module in the drop down list based on the ID you receive in the QueryString, for "Edit" mode just use the one in Model State.  But now in reality, what was happening is it was selecting correctly in "Edit" but was just being ignored in "Add", and for the life of me I could not figure out why.  It was just sitting there stating "-- Select --". I definitely had a "moduleid" in the QueryString, it definitely was lowercase and well, it definitely should have been marked with "selected".

So I thought, let's remove the complexity of the thing and just specifically tell the SelectList which ID I wish to select by passing it the value of 4. I definitely had an ID of 4, which I confirmed in viewing html source, but alas, still a failure using the below:

[sourcecode language='html']
<%= Html.DropDownList("ModuleMessageType.ModuleID", new SelectList(ViewData.Model.Modules, "ID", "Name", 4, "-- Select --", new { tabindex = 2, title = "Modules" })%>

This was getting ridiculous. I'm basically at the bottom-line here of what is within my control in order to mark the item as selected, so I started scouring through some of the ASP.NET MVC  RC 2 Source Code (intrepidly heading in like I knew what I was looking for) but it turns out I did, as for the Html.DropDownList() I noticed there appeared to be a priority-based implementation for the drop down list's decision on what item should be selected; and of course unfortunately, what you choose to enter into the selectedValue property appears to be the LAST port of call from what I could see.

The priority appears to be as follows:

  1. Value in Model State (Viewdata-supplied);
  2. Fallback to: value in selectedValue property (Parameter-supplied)


I gathered this from SelectExtensions.cs:117 of the ASP.NET MVC RC 2 Source Code:

object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(name, typeof(string[])) : htmlHelper.GetModelStateValue(name, typeof(string));

            // If we haven't already used ViewData to get the entire list of items then we need to
            // use the ViewData-supplied value before using the parameter-supplied value.
            if (!usedViewData) {
                if (defaultValue == null) {
                    defaultValue = htmlHelper.ViewData.Eval(name);
                }
            }

Interesting huh.  I personall feel this is a bit outrageous; the end-user's specification should always dictate the final operation I think (Consider CSS for example and classes vs. style). I do not know if this is by design of the ASP.NET MVC team, or a simple bug. Obviously they wished to implement an order of precidence, that part is clear, but to object what the user has entered into selectedValue due to a value being picked up elsewhere? Seems a bit odd to me.  I'd be interested to hear what others think.

So after understanding more about what's going on here and realising most likely what was occuring is that the value held in ViewData.Model.ModuleMessageType.ModuleID ("0") is the one chosen as the selectedValue, not the one I actually entered into selectedValue - thus resulting in no selection at all in my drop down list.

Considering this, I re-worked my code a little (and I'm happier with the end result anyway) plus with a small change to my controller which sets my ModuleID property to Request["moduleid"] (in instances whereby we're adding record) and changing my Html.DropDownList() slightly with removal entirely of the selectedValue property as follows it all worked correctly:
[sourcecode language='html']
<%= Html.DropDownList("ModuleMessageType.ModuleID", new SelectList(ViewData.Model.Modules, "ID", "Name"), "-- Select --", new { tabindex = 2, title = "Modules" })%>

You may be surprised as to how I can remove the declaration to the selectedValue property all together, but if you consider it, it is not needed. For both "add" and "edit" mode of my page it is gathered from my ViewData now, which based on rules above is exactly where the drop down list pulls it from.

Problem solved!

VN:F [1.9.1_1087]
Rating: 3.3/5 (8 votes cast)
VN:F [1.9.1_1087]
Rating: +2 (from 4 votes)
Unexpected Behaviour with ASP.NET MVC SelectList SelectedValue, 3.3 out of 5 based on 8 ratings
Bookmark and Share
kick it on DotNetKicks.com
Shout it

NOW, FOR A WORD FROM OUR SPONSORS

4 Comments

  1. You are voted!
    Track back from WebDevVote.com

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: +1 (from 1 vote)
    Posted on 23-Jun-09 at 8:31 pm | Permalink
  2. This is interesting.

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
    Posted on 14-Jul-09 at 9:42 am | Permalink
  3. Barry

    Good work, thanks.

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
    Posted on 11-Sep-09 at 3:53 am | Permalink
  4. Compe2001

    Great work man. This helped me a lot. :lol:

    VA:F [1.9.1_1087]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
    Posted on 26-Mar-10 at 7:40 am | Permalink

One Trackback/Pingback

  1. Interesting Finds: 2009-03-18 - Bolik on 19-Mar-09 at 1:13 am

    [...] Unexpected Behaviour with ASP.NET MVC SelectList SelectedValue [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*
My name is Graham O'Neale and I'm a software architect from Gold Coast, Australia. I am an overtime thinker, full time coder and awake part time in the real world. I have a keen interest in software development, particularly in the realm of programming (C#, ASP.NET, ASP.NET MVC, LINQ (2 SQL), Entity Framework, Silverlight, Blend, WCF, WPF) and a keen interest in the cutting edge and innovation. I have a new found love for design patterns, ALT.NET practices and well crafted software architecture. The purpose of this blog is to express any thoughts, findings, tips and gripes along my travels in the wonderful world of coding and technology...