When I am changing the "model => model.id"
to "model => model.Supplierid"
i am getting below error
"The parameter 'expression' must evaluate to an IEnumerable when multiple selection is allowed."
please have look on below code
// this 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 my controller
[HttpGet]
public ActionResult AddEditSupplier(int id)
{
clslistbox _lst = new clslistbox();
_lst.lstDocImgs= _lst.listDocImages();
return View(_lst);
}
// this is view where i am binding 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 it?
I think the changing of the property in the expression here is a red-herring - it won't work in either case.
Update
However, see at the end of my answer for some probably needlessly detailed exposition on why you didn't get an error first-time round.
End Update
You're using ListBoxFor
- which is used to provide users with multiple selection capabilities - but you're trying to bind that to an int
property - which cannot support multiple selection. (It needs to be an IEnumerable<T>
at least to be able to bind a list box to it by default in MVC)
I think you mean to be using DropDownListFor
- i.e. to display a list of items from which only one can be selected?
If you're actually looking for single-selection semantics in a listbox, that's trickier to do in MVC because it's Html helpers are geared entirely around listboxes being for multiple selection. Someone else on SO has asked a question about how to get a dropdown to look like a list box: How do I create a ListBox in ASP.NET MVC with single selection mode?.
Or you could generate the HTML for such a listbox yourself.
(Update) - Potentially needlessly detailed exposition(!)
The reason you don't get an exception first time round is probably because there was no value for id
in ModelState
when the HTML was generated. Here's the reflected MVC source (from SelectExtensions.SelectInternal
) that's of interest (the GetSelectListWithDefaultValue
call 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 first that the control variable allowMultiple
is true in your case, because you've called ListBoxFor
. selectList
is the SelectList
you create and pass as the second parameter. One of the things that MVC (unfortunately in some cases) does is to use ModelState
to modify the select list you pass when re-displaying a view in order to ensure that values which were set in ModelState
via a POST are re-selected when the view is reloaded (this is useful when page validation fails because you won't copy the values to your underlying model from ModelState
, but the page should still show those values as being selected).
So as you can see on the first line, the model's current value for the expression/field you pass is fished out of model state; either as a string array or as a string. If that fails (returns null
)then it makes another go to execute the expression (or similar) to grab the model value. If it gets a non-null value from there, it calls SelectExtensions.GetSelectListWithDefaultValue
.
As I say - what you're trying to do will ultimately not work in either the case of Id
or SupplierId
(because they would need to be IEnumerable
) but I believe this ModelState
->Eval
process is yielding a null value when you use Id
, so the process of getting an 'adjusted' SelectList
is skipped - so the exception doesn't get raised. The same is not true when you use SupplierId
because I'll wager that there's either a value in ModelState
at that point, or the ViewData.Eval
successfully gets an integer value.
Not throwing an exception is not the same as working!.
End update
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With