MVC Model Binding IList<T> data to Html.Listbox

你离开我真会死。 提交于 2020-01-24 17:12:30

问题


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.


回答1:


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.




回答2:


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




回答3:


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"))%>



回答4:


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.)



来源:https://stackoverflow.com/questions/1238679/mvc-model-binding-ilistt-data-to-html-listbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!