It’s surprising how many subtle, but frustrating traps one can fall into when building sites with
ASP.NET MVC. Creating forms for the web is one of them. It’s common to spend hours on something
trivial, such as displaying a selected value in a DropDownList on postback, or getting that selected
value in a controller. Quite often it happens when you just start learning ASP.NET MVC or upgrade
from an older tech. And boy, is this frustrating as hell – instead of building an actual web app,
you spend hours wrestling with the framework.
This article is one of the ‘DropDownList series’ articles that should help you in dealing with
DropDownList / SelectList / SelectListItem related problems. Check out other DropDownList articles
I want to show you how to build a simple form with a drop down list that’s got “Please select” text
as the first option and is based on the list of strings supplied by the controller. I’ll show you
how to display that list on a form, how to get user’s selection in the controller, check that user
has selected something and render the list back to the user with the value selected.
Sounds deceptively simple, right? Hold that thought for now and have a look at the Microsoft’s own
documentation for the @Html.DropDownListFor function. It has 6 different overloads – which
one of those do you really need? And what are those mysterious <TModel, TProperty> or
optionLabel? Now throw into the mix various ways you can pass the data into the view: ViewBag,
ViewData or TempData? Or maybe Model? So you are naturally in the perfect spot to start making
We need to clear this up once and for all. In this example I will take you through building a
simplistic “Sign Up” form that consists of two fields: Name and State. Both of these fields are
required – this way we can test rendering of selected dropdown list value on the postback.
The following bits and pieces are needed:
a model to hold user-entered data
a controller to handle user requests
a view that renders the “Sign Up” form
Here’s the complete code of the solution used in this article. You can also browse the
code online or clone the git repository. Now let’s dive right into the details.
As you can see model is pretty simple and reflects the form’s fields except for one property –
States. It works together with the State property – while the the State receives user’s
selection, States hold a list of all possible selections.
Controller’s a bit more complex - it consists of 3 action methods and a couple of utility functions.
The most important piece in the controller is the following code (and it’s repeated in both SignUp
As said above, this code runs twice – first when user loads the ‘Sign Up’ page in the browser and
the form is displayed, and second time when user submits the form.
Why does it need to happen twice? The nature of browser forms is such that only selected values
are posted back, and if you want to display the form after a postback (in case there’s a
validation error in one of the form’s controls, for example), you need to populate all the
supplementary data again, otherwise controls such as DropDownLists will be just rendered empty.
And View is the final destination where it all comes together with the help of
Again, the most important point to note here is the call of DropDownListFor() function. It does
all the heavy lifting when rendering a <select> tag with a bunch of <option> tags.
As you can tell from the comments, its first argument m => m.State is used to store and retrieve
selected value, and its second argument Model.States is used to supply all possible selections for
the dropdown. In the end you get something like this sent to user’s browser:
Oh, and remember that cryptic optionLabel argument of DropDownListFor function? It’s actually used to render
the ‘prompt’ option of the drop down list. I’d never be able to tell that from the name alone!
Here’s a download link to the complete code of the solution used in this article. You can
browse the code online or clone the git repository.
But wait, there’s more
If you don’t want to miss my new articles, sign up to my mailing list below, and learn how to
tackle complex problems in ASP.NET MVC with ease, and how to stop wasting hours on trivial problems.
Stop that vicios frustration cycle and become a better person overall. I never spam, period.
Download fully tested and 100% working Visual Studio solution with the
source code used in this article for FREE - just enter your name and email in
the form below, and I’ll send you the download link right away!
Not only you’ll get the complete code for this article, you’ll also get access to
all the source code for all the articles on the site forever, as well as the access to
my mailing list, which receives handy time-saving tips on .NET programming.