MVC Model Binding IList data to Html.Listbox

2019-07-11 17:50发布

I want to bind my Store class which has multiple Products to Html.Listbox. While in edit Store mode, I want Html.Listbox show all products where products of the Store are selected. I could not manage to bind store.Products to the listbox

My class structure;

public class Store
{
   public virtual int Id { get; set; }  
   public virtual string Name { get; set; }       
   public virtual IList<Product> Products { get; set; }
}
public class Product
{
   public virtual int Id { get; set; }  
   public virtual string Name { get; set; }       
}
public class StoreEditView
{
   public virtual int Id { get; set; }  
   public virtual string Name { get; set; }       
   public virtual IList<Product> Products { get; set; }
   public virtual MultiSelectList ProductList //populated from db, all products in the form of IList<Product>
}

My controller;

  public ViewResult Edit()
  {
    var editstore = new StoreEditView();
    editstore.Products = new List<Product> {new Product() {Id = 1, Name="Example"}};
    return View(editstore);
  }

My View;

 <%=Html.ListBox("Products", Model.ProductList)%>

In this case, I need product.Id=1 to be shown selected in the listbox. So far I couldn't do it. I tried,

<%=Html.ListBox("Product.Id", Model.ProductList)%>
<%=Html.ListBox("Products.Id", Model.ProductList)%>

just didn't work.

4条回答
一夜七次
2楼-- · 2019-07-11 18:19

Assuming that Store is your Model:

<%= Html.ListBox("ProductList",
        new SelectList(Model.Products, "Id", "Name", 1)) %>

The key is that the ListBox must be named differently than the SelectList! I don't know if this is a bug in ASP.NET MVC 1.0 (it looks so) but I also spent some time figuring it out before. The symptom is that no value is ever selected. I hope that this solves the issue for you and you can get rid of that StoreEditView class, which I think is unnecessary.

查看更多
不美不萌又怎样
3楼-- · 2019-07-11 18:24

Thanks for your inputs. Both methods work, but when you submit the page - mvc can't model bind Product listbox to Store object by default.

I managed to solve this problem by using AutoMapper (A convention-based object-object mapper.)

查看更多
可以哭但决不认输i
4楼-- · 2019-07-11 18:40

Please refer the article which describes how to bind MVC listbox: http://www.altafkhatri.com/Technical/How_to_bind_IList_with_MVC_Dropdownlist_box

查看更多
来,给爷笑一个
5楼-- · 2019-07-11 18:43

Based on your revision, maybe you need this in the code that populates your select list:

List<int> selectedValues = new List<int>();
foreach (Product p in store.Products)
    selectedValues.Add(p.Id);
var allProductList = new MultiSelectList(allProducts, "Id", "Title", selectedValues);

I'll leave my original answer below because it would solve the problem in a cleaner fashion.

The Html.ListBox() helper wants an IEnumerable passed to it so you need to convert your list to that in order to populate the list box.

You can accomplish this with an extension method like this:

using System.Collections.Generic;
using System.Web.Mvc;

namespace MvcMockups.Extensions
{
    public static class Extensions
    {
        public static SelectList ToSelectList<T>(this IEnumerable<T> items, string dataValueField, string dataTextField, string selectedValue)
        {
            return new SelectList(items, dataValueField, dataTextField, selectedValue);
        }
    }
}

Your view will need to know about your extension method:

<%@ Import Namespace="MvcMockups.Extensions"%>

Then your view would contain:

<%= Html.ListBox("Product", Model.Products.ToSelectList("Id", "Name", "1"))%>
查看更多
登录 后发表回答