Question

I have a @Html.DropDownListFor that is displaying a list of items from my database.

Very simplified I have a ViewModel with these paramaters

public class RegisterViewModel
{
    [Required]
    [Display(Name = "Country")]
    public string SelectedCountryId { get; set; }
    public IEnumerable<System.Web.Mvc.SelectListItem> CountryList { get; set; }

    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }
}

I am then in my controller populating the IEnumerable<System.Web.Mvc.SelectListItem>with this:

    IEnumerable<SelectListItem> countries = _DB.Countries.Where(x => x.Status == Status.Visible)
                        .Select(x => new SelectListItem()
                        {
                            Value = x.ID + "",
                            Text = "(+" +x.PhoneCountryCode + ") - " + x.Name
                        }).ToList();
    countries.First().Selected = true;

I'm then using the following HTML to display the optionset

@Html.DropDownListFor(m => m.SelectedCountryId, Model.CountryList, new { @class = "form-control" })

The optionlist always has the first option selected when the page loads and if you click it there are three options to chose from.

My problem is that if you don't open the list and select an item (ie just leave it on the default value) this error is thrown from my view,

The ViewData item that has the key 'SelectedCountryId' is of type 'System.String' but must be of type 'IEnumerable'.

This error does not occur if you open the dropdown and select an item manually. If I select some other item from the list SelectedCountryId does get the proper value.

I tried switching out the public string SelectedCountryId { get; set; } from a string to IEnumerable<SelectListItem> instead, and this did make the error go away, but the list is always empty.

Any bright ideas?

Was it helpful?

Solution

In your controller When the model is not valid , repopulate the dropdown:

if (ModelState.IsValid)
{
IEnumerable<SelectListItem> countries = _DB.Countries.Where(x => x.Status == Status.Visible)
                    .Select(x => new SelectListItem()
                    {
                        Value = x.ID + "",
                        Text = "(+" +x.PhoneCountryCode + ") - " + x.Name
                    }).ToList();
countries.First().Selected = true;
}
else
{
  //We need to rebuild the dropdown or we're in trouble
   IEnumerable<SelectListItem> countries = _DB.Countries.Where(x => x.Status == Status.Visible)
                        .Select(x => new SelectListItem()
                        {
                            Value = x.ID + "",
                            Text = "(+" +x.PhoneCountryCode + ") - " + x.Name
                        }).ToList();
    countries.First().Selected = true;
}

You can also check the errors in the model state by using this. Might be something interesting there:

var errors = ModelState
                .Where(x => x.Value.Errors.Count > 0)
                .Select(x => new { x.Key, x.Value.Errors })
                .ToArray();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top