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
here:
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
mistakes.
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.
Model
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
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
methods):
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.
View
And View is the final destination where it all comes together with the help of
Html.DropDownListFor() function.
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!
Get complete, tested, and working source code for this article
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.
You will also get access to all the source code for all existing and new
articles on the site, and access to my mailing list, which receives handy
timesaving tips on .NET Core programming.
Subscribe now and get helpful tips on developing .NET apps - never miss a new article.