我正在关注此Tutorial on ASP.NET MVC,特别指出向Razor View提供"MovieType"
的字符串如下:@Html.DropDownList("MovieType")
将提供 DropDownList 在ViewBag
类型的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");
}
}
Razor 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时,这是由Entity Framework自动生成的。
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; }
}
}
答案 0 :(得分: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
继承自实现IEnumerable<SelectListItem>
的{{3}}。
答案 1 :(得分:2)
按照Peter G.在答案中提到的那样,但仅出于提供信息的目的,您还应该能够将Post控制器更改为:
[HttpPost]
public ActionResult Create(Product product, int ListItems)
{
}
正如Peter所提到的(再次使用他的回答),问题是当你的表单发布时,你的DropDown列表的名称为“ListItems”,你的控制器上没有任何内容可以绑定它。
答案 2 :(得分:0)
我最终做了以下事情:
<强>控制器强>
...
[HttpPost]
public ActionResult Create(Product product)
{
var categoryId = product.CategoryId;
repository.SaveProduct(product);
return RedirectToAction("Index");
}
...
Razor 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
,但随后会将其标记为红色,我会收到运行时错误。