1

我正在关注ASP.NET MVC 上的本教程,特别是其中指出将 String of 提供"MovieType"给 Razor 视图如下:@Html.DropDownList("MovieType")将提供DropDownListViewBag的密钥以在of 类型中查找属性IEnumerable<SelectListItem>

这工作得很好。

但是,我无法使用[HttpPost]属性获取用户在我的方法上选择的值。

这是我的代码以及迄今为止我尝试过的代码。

控制器

public class ProductController : Controller 
{
    private readonly ProductRepository repository = new ProductRepository();

    // Get: /Product/Create
    public ActionResult Create()
    {
        var categories = repository.FindAllCategories(false);
        var categorySelectListItems = from cat in categories
                                      select new SelectListItem()
                                          {
                                              Text = cat.CategoryName,
                                              Value = cat.Id.ToString()
                                          };
        ViewBag.ListItems = categorySelectListItems;
        return View();
    }

    [HttpPost]
    public ActionResult Create(Product product)
    {
        /** The following line is not getting back the selected Category ID **/
        var selectedCategoryId = ViewBag.ListItems;
        repository.SaveProduct(product);
        return RedirectToAction("Index");
    }
}

剃须刀 cshtml 查看

@model Store.Models.Product

<h2>Create a new Product</h2>

@using (@Html.BeginForm())
{
    <p>Product Name:</p>
    @Html.TextBoxFor(m => m.ProductName)

    <p>Price</p>
    @Html.TextBoxFor(m => m.Price)

    <p>Quantity</p>
    @Html.TextBoxFor(m => m.Quantity)

    <p>Category</p>
    @Html.DropDownList("ListItems")
    <p><input type="submit" value="Create New Product"/></p>
}

我尝试使用 的重载DropDownList,但我无法取回用户选择的值。

如果有人看到我所缺少的或有任何想法或建议,我将不胜感激。谢谢!

更新

发布Product模型。请注意,这是在我创建 .edmx 时由实体框架自动生成的。

namespace Store.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Product
    {
        public long Id { get; set; }
        public string ProductName { get; set; }
        public decimal Price { get; set; }
        public int Quantity { get; set; }
        public System.DateTime DateAdded { get; set; }
        public Nullable<long> CategoryId { get; set; }

        public virtual Category Category { get; set; }
    }
}
4

3 回答 3

6

您正在将类型模型传递Store.Models.Product到您的视图中。其他字段使用 lambda 表达式绑定到此模型,但@Html.DropDownList()不绑定到模型,因此当模型在 HTTPPost 中返回时,选择不存在。

您需要将Category字段添加Store.Models.Product到该列表,然后使用以下方法绑定到该列表:

@Html.DropDownListFor(m => m.Category, ViewBag.ListItems)

然后 MVC 应该正确地将您的输入控件绑定到模型。

例如,此语法确实有效:

int[] listItems = {1, 2, 3, 4};
SelectList selectList = new SelectList(listItems);
@Html.DropDownListFor(m => m.CategoryId, selectList);

请注意,SelectList继承自MultiSelectListwhich implements IEnumerable<SelectListItem>

于 2013-03-29T19:08:08.443 回答
2

遵循 Peter G. 在他的回答中提到的内容,但仅供参考,您还应该能够将您的 Post 控制器更改为:

[HttpPost]
public ActionResult Create(Product product, int ListItems)
{

}

正如彼得所提到的(再次使用他的答案),问题是当您的表单发布时,您的下拉列表的名称为“ListItems”,并且您的控制器上没有任何东西可以绑定。

于 2013-03-29T19:14:59.280 回答
0

我最终做了以下事情:

控制器

...
    [HttpPost]
    public ActionResult Create(Product product)
    {
        var categoryId = product.CategoryId;
        repository.SaveProduct(product);
        return RedirectToAction("Index");
    }
...

剃须刀 cshtml 查看

...
<p>Category</p>
@Html.DropDownList("CategoryId", (IEnumerable<SelectListItem>) ViewData["ListItems"])
... 

它看起来很丑,老实说,我不完全理解为什么我不能像 Peter 建议的那样使用 lambda 表达式,@Html.DropDownListFor(m => m.CategoryId, ViewBag.ListItems).

对我来说,我已经“让它工作”,但想了解为什么,如果有更优雅的方式我可以做到。

当我输入 时@Html.DropDownListFor(m => m.CategoryId, ViewBag.ListItems),IntelliSense 会自动填充m.CategoryId,但随后会将其标记为红色,并且会出现运行时错误。

于 2013-03-29T19:29:07.343 回答