0

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?

JensB
  • 6,663
  • 2
  • 55
  • 94

1 Answers1

1

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();
JensB
  • 6,663
  • 2
  • 55
  • 94
meda
  • 45,103
  • 14
  • 92
  • 122
  • This was not the problem, but led me to what the problem was. The real problem was `ModelState.IsValid == false` and this was caused by another unrelated custom property attribute, I figured this out by going through the error list in the `ModelState`. Still weird that the error was being shown on the DropDownFor field.. Thanks for help! – JensB May 15 '14 at 16:48
  • Welcome, since i led you to the solution , can i earn the approved answer?? ;) – meda May 15 '14 at 16:53