model.id" to "model => model.Supplierid" , I get below the error ...">

Getting Error During ListBox Binding For Control in MVC4

When I change "model => model.id" to "model => model.Supplierid" , I get below the error

The "expression" parameter must be evaluated in IEnumerable when multiple selection is allowed.

please see below code

// this is my model class

 public class clslistbox{ public int id { get; set; } public int Supplierid { get; set; } public List<SuppDocuments> lstDocImgs { get; set; } public class SuppDocuments { public string Title { get; set; } public int documentid { get; set; } } public List<SuppDocuments> listDocImages() { List<SuppDocuments> _lst = new List<SuppDocuments>(); SuppDocuments _supp = new SuppDocuments(); _supp.Title = "title"; _supp.documentid = 1; _lst.Add(_supp); return _lst; } } 

// this is my controller

  [HttpGet] public ActionResult AddEditSupplier(int id) { clslistbox _lst = new clslistbox(); _lst.lstDocImgs= _lst.listDocImages(); return View(_lst); } 

// this is the view where I bind listboxfor

 @model clslistbox @using (Html.BeginForm("AddEditSupplier", "Admin", FormMethod.Post)) { @Html.ListBoxFor(model => model.id, new SelectList(Model.lstDocImgs, "documentid", "title")) } 

Can anyone see the reason for this?

+6
source share
2 answers

I think that changing the property in the expression here is a red herring - it won't work anyway.

Update

However, see the end of my answer for some probably unnecessary detail on why you didn't get the error the first time.

Final update

It uses a ListBoxFor , which is used to provide users with multiple choices, but you are trying to bind it to an int property that cannot support multiple selections. (It should be IEnumerable<T> , at least be able to bind a default list to it in MVC)

I think you want to use DropDownListFor - for example, to display a list of elements from which you can select only one of them?

If you are really looking for semantics with one choice in a list, this is harder to do in MVC because its Html helpers are fully oriented to a list intended for multiple selection. Someone else at SO asked how to get a drop-down list so that it looks like a list box: How do I create a ListBox in ASP.NET MVC with one select mode? .

Or you can create HTML code for such a list yourself.

(Update) - Potentially unnecessary detailed exposition (!)

The reason you don't get the exception for the first time is probably because when creating the HTML there was no value for the id in ModelState . Here's the MVC source of interest to you (from SelectExtensions.SelectInternal ) (calling GetSelectListWithDefaultValue at the end is the source of your exception):

 object obj = allowMultiple ? htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(string[])) : htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(string)); if (!flag && obj == null && !string.IsNullOrEmpty(name)) { obj = htmlHelper.ViewData.Eval(name); } if (obj != null) { selectList = SelectExtensions.GetSelectListWithDefaultValue(selectList, obj, allowMultiple); } 

Note that the allowMultiple control variable is allowMultiple in your case because you called ListBoxFor . selectList is a selectList that you create and pass as the second parameter. One of the things that MVC (unfortunately, in some cases) does is to use ModelState to change the selection list that you pass when the view is displayed again, to ensure that the values ​​that were set in ModelState via POST are selectable. when the view reloads (this is useful if the page is not checked, because you will not copy the values ​​to your base model from ModelState , but the page should show these values ​​as selected).

Thus, as you can see in the first line, the current value of the model for the expression / field you are transmitting is issued from the state of the model; either as a string array or as a string. If this does not work (returns null ), then it forces another to execute the expression (or similar) to capture the model value. If it gets a non-zero value from there, it calls SelectExtensions.GetSelectListWithDefaultValue .

As I said, what you are trying to do will ultimately not work in the case of id , nor SupplierId (because they must be IEnumerable ) , but I that this ModelState β†’ Eval process gives a null value when using id , therefore the process of getting the "adjusted" selectList skipped - therefore, an exception does not occur. The same is not true if you use SupplierId , because I will fend off that at this point there is either a value in ModelState , or ViewData.Eval successfully receives an integer value.

Do not throw an exception, since it works !

Final update

+15
source

Try changing the property from int to int []

  public class SuppDocuments { public string Title { get; set; } public int documentid { get; set; } } 

Assuming this is the class used to bind the model, try changing the documentid property below

  public class SuppDocuments { public string Title { get; set; } public int[] documentid { get; set; } } 
0
source

All Articles