【问题标题】:Binding ListBox with a model in MVC3在 MVC3 中将 ListBox 与模型绑定
【发布时间】:2012-08-13 13:21:46
【问题描述】:

我的模特是

public class SiteConfig
{
    public SiteConfig()
    {

    }

    public int IdSiteConfig { get; set; }
    public string Name { get; set; }
    public byte[] SiteLogo { get; set; }
    public string Brands { get; set; }
    public string LinkColour { get; set; }

    public IEnumerable<SiteBrand> SiteBrands { get; set; }
}

public class SiteBrand
{
    public int Id { get; set; }
    public int SiteId { get; set; }
    public int BrandId { get; set; }

    public Brand Brand { get; set; }
    public SiteConfig SiteConfig { get; set; }
}

public class Brand
{
    public int BrandId { get; set; }
    public string Name { get; set; }

    public IEnumerable<SiteBrand> SiteBrands { get; set; }
}

我遵循数据库第一方法。每个 SiteConfig 记录可以包含一个或多个品牌。所以 Brand 正在保存到另一个名为 SiteBrand 的表中。

SiteBrand 包含对 SiteConfig(on IdSiteConfig) 和 Brand(BrandId) 的外键引用。

当我创建站点配置时,我想将所有可用品牌显示为列表框,用户可以在其中选择一条或多条记录(可能不选择任何品牌)。

但是当我将视图与模型绑定时,如何将列表框绑定到品牌列表以及发布视图时如何获取所选品牌。

我必须将 SiteConfig 对象与所​​选项目一起保存到数据库中。这是我的数据库图。

这是我保存到数据库的 DAL。

public SiteConfig Add(SiteConfig item)
    {
        var siteConfig = new Entities.SiteConfig
            {
                Name = item.Name,
                LinkColour = item.LinkColour,
                SiteBrands = (from config in item.SiteBrands
                              select new SiteBrand {BrandId = config.BrandId, SiteId = config.SiteId}).
                    ToList()
            };
        _dbContext.SiteConfigs.Add(siteConfig);
        _dbContext.SaveChanges();
        return item;
    }

谁能教教如何绑定列表框并获取选中项。

谢谢。

【问题讨论】:

    标签: asp.net-mvc-3 c#-4.0 asp.net-mvc-4 asp.net-mvc-areas ef-database-first


    【解决方案1】:

    向您的 SiteConfig ViewModel 添加一个字符串数组类型的新属性。当用户发布此表单时,我们将使用它从Listbox 获取选定项。

    public class SiteConfig
    {
      //Other properties here
      public string[] SelectedBrands { get; set; }  // new proeprty
      public IEnumerable<SiteBrand> SiteBrands { get; set; }
    }
    

    在您的 GET 操作方法中,获取 SiteBrands 列表并分配给 SiteConfig ViewModel 对象的 SiteBrands 属性

    public ActionResult CreateSiteConfig()
    {
        var vm = new SiteConfig();
        vm.SiteBrands = GetSiteBrands();
        return View(vm);
    }
    

    出于演示目的,我只是对方法进行了硬编码。当您实现这一点时,您可能会从您的数据访问层获取数据。

    public IList<SiteBrand> GetSiteBrands()
    {
        List<SiteBrand> brands = new List<SiteBrand>();
        brands.Add(new SiteBrand { Brand = new Brand { BrandId = 3, Name = "Nike" } });
        brands.Add(new SiteBrand { Brand = new Brand { BrandId = 4, Name = "Reebok" } });
        brands.Add(new SiteBrand { Brand = new Brand { BrandId = 5, Name = "Addidas" } });
        brands.Add(new SiteBrand { Brand = new Brand { BrandId = 6, Name = "LG" } });
        return brands;
    }
    

    现在在你的视图中,它被强类型化为SiteConfig ViewModel,

    @model SiteConfig
    <h2>Create Site Config</h2>
    @using (Html.BeginForm())
    {
      @Html.ListBoxFor(s => s.SelectedBrands, 
                    new SelectList(Model.SiteBrands, "Brand.BrandId", "Brand.Name"))
      <input type="submit" value="Create" />
    }
    

    现在,当用户发布此表单时,您将在 ViewModel 的 SelectedBrands 属性中获得 Selected Items 值

    [HttpPost]
    public ActionResult CreateSiteConfig(SiteConfig model)
    {
        if (ModelState.IsValid)
        {
            string[] items = model.SelectedBrands;
            //check items now
            //do your further things and follow PRG pattern as needed
        }
        model.SiteBrands = GetBrands();
        return View(model);
    }
    

    【讨论】:

    • 感谢您的回复。当我在模型中提交表单时,我得到了选定的 ID。但我将 SiteBrands 设为空。如果我必须保存我的模型,我是否需要使用所选项目创建 SiteBrands 集合并提交?或者还有其他更好的方法吗?
    • 为什么在创建 Siteconfig 时需要 SiteBrands 集合?我想您需要 ListBox 中的 Selected Items (这就是您在最初的问题中提出的问题)。但是如果你再次渲染同一个视图,那么你需要在将视图模型返回给视图之前再次重新分配 SiteBrands,因为 HTTP 是无状态的
    • 因为我的 Create 方法采用 SiteConfig 类型的对象。我的数据库只知道 SiteBrands。 Id 对 Selected id 一无所知。正如我在问题中解释的那样,SiteBrand 包含对网站 ID 和品牌 ID 的外键引用。
    • 您需要读取所选项目(具有 IDS)并将其传递给您的数据访问层,该层将这些数据保存在您的后端)。由于我不了解您的数据访问层,因此我无法确切告诉您该怎么做
    • 刚才我发布了我的数据库图和创建方法。您能否建议我这样做的更好方法。谢谢。
    【解决方案2】:

    您可以拥有一个同时包含网站和品牌模型的“ViewModel”。然后您可以将您的视图绑定到该模型。这将允许您将视图的任何部分绑定到任何底层模型的任何部分。

    public class siteViewModel{
        public SiteConfig x;
        public Brand b; //Fill this with all the available brands
    }
    

    当然,您可以包含您的视图可能需要的任何其他信息(也减少了 ViewBag 的需求)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多