如何将下拉列表选择保存回数据库

时间:2014-02-19 17:36:24

标签: c# asp.net-mvc-4 razor

我的下拉列表正在拉动并显示正确的列表,但是一旦选中,我会点击保存并忽略所选的选项,并且值再次为空。

//获取

public ActionResult Edit(int id)
{
    Prospect prospect = db.Prospects.Find(id);
    if (prospect == null)
    {
        return HttpNotFound();
    }
    ViewBag.ProductID = new SelectList(db.Products, "ProductID", "Name", prospect.Product);
    return View(prospect);
}

//发布

    [HttpPost]
    public ActionResult Edit(Prospect prospect)
    {
        if (ModelState.IsValid)
        {
            db.Entry(prospect).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.ProductID = new SelectList(db.Products, "ProductID", "Name", prospect.Product);
        return View(prospect);
    }

//视图

    <div class="editor-label">
        @Html.LabelFor(model => model.Product)
    </div>
    <div class="editor-field">
        @Html.DropDownList("ProductId", String.Empty)
        @Html.ValidationMessageFor(model => model.Product)
    </div>

非常感谢任何帮助

2 个答案:

答案 0 :(得分:4)

仅限助手(显示除外)与模型绑定。将您的下拉列表更改为

@Html.DropDownListFor(x => x.ProductID, (SelectList)ViewBag.ProductID)

其中ProductID是您希望所选项目绑定到的模型中的任何值。您还可以通过在将该值传递给视图之前设置该值来设置下拉列表

更新

我同意Muffin Mans的回答。使用ViewBag向视图发送下拉列表可能不可靠。一个不同的方式来给松饼人提供答案

向模型添加列表

public List<SelectListItem> Products { get; set; }

然后在您的控制器上从数据库中填充该列表。松饼人提供了一种方法。我们以不同方式访问我们的数据,因此我使用foreach填充我的列表

var products = //populate the list from your database
List<SelectListItem> ls = new List<SelectListItem>();
foreach(var temp in products){
    ls.Add(new SelectListItem() { Text = temp.ProductName, Value = temp.ProductID });
}
Model.Products = ls; // set the list in your model to the select list you just built

然后在您的视图上,而不是将视图包列表转换为选择列表,您只需从模型中引用列表

@Html.DropDownListFor(x => x.ProductID, Model.Products)

答案 1 :(得分:1)

您不应该将视图直接绑定到数据库表类型。使用视图模型。此外,此类数据属于视图模型,而不属于viewbag。视图包非常适合在视图和布局页面之间共享页面标题等内容。

public class ProspectViewModel
{
    public IEnumerable<SelectListItem> ProspectList { get; set; }

    [DisplayName("Product")] //This is for our label
    public int SelectedProspectId { get; set; }
}

获取

public ActionResult Edit(int id)
{
   var prospect = db.Prospects.Find(id);
   if (prospect == null)
   {
       return HttpNotFound();
   }

   var model = new ProspectViewModel
                   {
                      ProductList = db.Products.Select(x=> new SelectListItem { ... })
                   };

   return View(model);
}

发布

[HttpPost]
public ActionResult Edit(ProspectViewModel model)
{
    if (ModelState.IsValid)
    {
        var prospect = new Prospect { /* populate with values from model */  };
        db.Prospects.Attach(prospect);
        db.Entry(prospect).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    //Need to repopulate drop down list
    //And we don't need to set SelectedProductId because it's already been posted back
    model.ProductList = db.Products.Select(x=> new SelectListItem { ... });

    return View(model);
}

查看

<div class="editor-label">
    @Html.LabelFor(model => model.SelectedProductId)
</div>
<div class="editor-field">
    @Html.DropDownListFor(x=> x.SelectedProductId, Model.ProductList)
    @Html.ValidationMessageFor(x=> x.SelectedProductId)
</div>

这超出了本答案的范围,但您不应该在控制器中进行数据访问。微软的例子表明了这一点,因为它们是“Hello world”的例子,不一定是字面意思。