Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The ViewData item that has the key 'XXX' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>' [duplicate]

Pretty new to MVC. I get the following exception when trying to submit my form that contains a static DropDownListFor.

The ViewData item that has the key 'CurrentPosition' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: The ViewData item that has the key 'CurrentPosition' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>'.

Source Error: 


Line 36:            @Html.LabelFor(m => m.CurrentPosition, new { @class = "col-md-2 control-label" })
Line 37:            <div class="col-md-10">
Line 38:                @Html.DropDownListFor(m => m.CurrentPosition, ViewData["Positions"] as SelectList)
Line 39:                @Html.ValidationMessageFor(m => m.CurrentPosition, "", new { @class = "text-danger" })
Line 40:            </div>

Model:

[Display(Name = "Current Position")]
[Required(ErrorMessage = "Please select their current position")]
public string CurrentPosition { get; set; }

View:

<div class="form-group">
    @Html.LabelFor(m => m.CurrentPosition, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.DropDownListFor(m => m.CurrentPosition, ViewData["Positions"] as SelectList)
        @Html.ValidationMessageFor(m => m.CurrentPosition, "", new { @class = "text-danger" })
    </div>
</div>

Controller:

[HttpGet]
public ActionResult Sales()
{
    var positions = new SelectList(new []
    {
        new { value = 0, text = "Select a Position..." },
        new { value = 1, text = "Merchandiser" },
        new { value = 2, text = "ISR" },
        new { value = 3, text = "TM" },
        new { value = 4, text = "AISR" },
        new { value = 5, text = "TAM" },
        new { value = 6, text = "BAM" },
        new { value = 7, text = "CSR" },
        new { value = 8, text = "Director" },
        new { value = 9, text = "TSM" },
        new { value = 10, text = "Tel-Sell" },
        new { value = 11, text = "Graphics" },
        new { value = 12, text = "Shelf Set" },
        new { value = 13, text = "Secretary" },
        new { value = 14, text = "POS" },
        new { value = 15, text = "Other" }
    },
    "value", "text", 1);

    ViewData["Positions"] = positions;

    return View();
}

I've already tried several different ways and can only seem to get this to work if I populate the list items directly in the view statically, which I don't find correct as I will be using this list again in this view. What do you think?

Edit: Post action. It's empty for right now.

[HttpPost]
public ActionResult Sales(SalesViewModel model)
{
    return View(model);
}
like image 925
justiceorjustus Avatar asked Sep 14 '16 17:09

justiceorjustus


1 Answers

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

Usually you get this error when you submit the form to an http post action method and inside that you are returning the same (view)model back to the view without reloading the data needed to render the SELECT element.

I guess your current code is something like this

[HttpPost]
public ActionResult Sales(SomeViewModel model)
{
   if(ModelState.IsValid)
   {
     // to do : Save and Redirect (PRG pattern)
   }
   return View(model);
}

Since our view code is using the data set to ViewData dictionary, You need to make sure that you are reloading ViewData["Positions"] before calling the return View().

[HttpPost]
public ActionResult Sales(SomeViewModel model)
{
    var positions = new SelectList(new []
    {
       new { value = 0, text = "Select a Position..." },
       new { value = 1, text = "Merchandiser" },
       new { value = 8, text = "Director" }
   },"value", "text", 1);

   ViewData["Positions"] = positions;  // Reloading the data here
   return View(model);
}

If you are not using ViewData/ViewBag, but using a view model, you need to do the same. Reload the view model property to the collection needed to populate the SELECT element.

like image 158
Shyju Avatar answered Nov 16 '22 01:11

Shyju