I’ve been struggling for a while to find a decent example of how dropdown lists work in ASP.Net MVC. It seems like a pretty simple thing to do – show a dropdown list with a selected item, allow the user to select a different item then save the new selection back on the server when the user submits the form containing the dropdown. However, it took me a few hours of searching and experimenting to get my dropdown working.
Here’s how I got it working …
1. In the model used to pass data to the view, ensure there are two fields – one containing the list of items to show in the list on the web page, the other field containing the value of the selected item. Here’s a cut down version of my model class:
public class CustomerModelData { // The list of payment terms. This is a list of strings // converted into the SelectList type for use by the // Html.DropDownList HTML helper. // public SelectList PaymentTerms { get; set; } // The value of the selected item. Note that this is // a string, i.e. the same type as the list members. // // Note that the name of this field is used by the // Html.DropDownList helper later in the example. // public String PaymentTermID { get; set; } }
2. In the controller, when the view is initially loaded, populate the model fields above with the list of items for the dropdown and the value of the selected item.
// Load the data from the database. // CustomerModelData Model = new CustomerModelData(); List<PaymentTermData> DBTerms = DatabaseManager.PaymentTerms; List<String> DBTermsText = new List<string>(); foreach (PaymentTermData PT in DBTerms) { DBTermsText.Add(PT.ToString()); } PaymentTermData SelectedTerm = DatabaseManager.SelectedTerm(); // Set the list of items for display converting from a // list of strings to a SelectList. // Model.PaymentTerms = new SelectList(DBTermsText); // Set the selected item for the drop down. // Model.PaymentTermID = SelectedTerm.ToString();
3. In the view, plase the Html.DropDownList helper:
@Html.DropDownList("PaymentTermID", Model.PaymentTerms)
Note that there are two parameters to the DropDownList call:
a. “PaymentTermID” – This is the name of the field in the model that contains the selected item.
b. Model.PaymentTerms – This is the list of items for the drop down.
4. When the user makes a selection on the drop down and then submits the form containing the drop down, e.g. by pressing the Save or Submit button on the form, the same model class (CustomerModelData) can be used to pass data back to the controller:
[HttpPost] public ActionResult CustomerDetails(CustomerModelData Data) { // The value chosen by the user is now held in the model. // String TheSelectedValue = Data.PaymentTermID;
// The list of values is NOT passed back to the controller. // This field is now null. // SelectList TheValues = Data.PaymentTerms;
Note that the value selected by the user has been updated in the model BUT that the list of values is now null. If the view is reloaded at the end of the controller action, the list will need to be repopulated in the model.
There may be other, more efficient ways of handling dropdown lists in ASP.Net MVC but this example works for me and took a surprising amount of time and trials to get to a working state. Initially, I had tried to think of the DropDownList helper as though it was a Winforms combo box where I could pass a list of objects, e.g. the actual PaymentTermData class, together with an instance of the class as the selected item. However this didn’t work and in the end I reverted to a simple type (String) for both the list and selected item in the drop down.
Also check out this post http://www.sliqtools.co.uk/blog/net/asp-net-mvc-disable-cache-to-keep-ajax-working-ok/ for tips on disabling the cache with Ajax requests as I have come across situations where the dropdownlist (and other stuff) appears not to work with the caching enabled.