ASP.NET MVC ListBox does not show the selected lis

2019-03-02 19:43发布

问题:

I am in a big trouble. I read 4 stackoverflow question and one blogpost. I have tried 5 different approach to view the selected items in a multiple selectlist.

I have no success.

The multiple selectlist is generated, but it does not select the items. I have no more idea.

Model:

public class EditableModel
{
     public IList<Company> SelectedCompanies { get; set; }
     public IList<SelectListItem> SelectListCompanies { get; set; }
}

Controller:

public ActionResult Edit(int id)
{
     var service = _serviceDAL.GetEditableModel(id);

     if (service!= null)
     {
          service.SelectListCompanies = GetSelectListCompanies(service.SelectedCompanies);
          return View(service);
     }
}

private IList<SelectListItem> GetSelectListCompanies(IList<Company> selectedCompanies)
{
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (Companycompany in _companyService.GetCompanies())
        {
            items.Add(new SelectListItem
            {
                Value = company.CompanyId.ToString(),
                Text = company.Name,
                Selected = selectedCompanies.Any(x => x.CompanyId == company.CompanyId)
            });
        }
        return items;
}

View

@Html.ListBox("SelectedCompanies", Model.SelectListCompanies, Model.SelectedCompanies.Select(x => x.CompanyId.ToString()) )

And nothing. The items in the select list is not selected...

I have tried this Multiselect, the same result, or this one as the current solution.

回答1:

You cannot bind a <select multiple> to a collection of complex objects. It binds to, and posts back an array of simple values (the values of the selected options).

Your SelectedCompanies property needs to be IEnumerable<int> (assuming the CompanyId of Company is also int). Note also the Selected property of SelectListItem is ignored when binding to a property.

Your also using the same collection for the selected Companies and the list of all Companies which makes no sense. Your SelectListCompanies should be generated from your table of Company.

Model

public class MyViewModel
{
     public IEnumerable<int> SelectedCompanies { get; set; }
     public IEnumerable<SelectListItem> SelectListCompanies { get; set; }
}

Base on your current code for EditableModel, your code should be

public ActionResult Edit(int id)
{
    var service = _serviceDAL.GetEditableModel(id);
    ....
    MyViewModel model = new MyViewModel
    {
        SelectedCompanies = service.SelectedCompanies.Select(x => x.CompanyId),
        SelectListCompanies = GetSelectListCompanies()
    };
    return View(model);

private IEnumerable<SelectListItem> GetSelectListCompanies()
{
    var all companies = ... // call method to get all Companies
    return companies.Select(x => new SelectListItem
    {
        Value = x.CompanyId.ToString(),
        Text = x.Name
    });
}

However, it look like you should be modifying your EditableModel and the GetEditableModel() code to return the correct data in the first place.