下载mvc3编辑表单

这可能很简单,但我似乎无法自己解决。 我创建了一个简单的数据库和实体模式,看起来像这样

在此处输入图像描述

我正在尝试创建一个允许我添加新订单的创建表单。 我总共有3个表,所以我要做的是让表格允许此人输入订单日期,还有一个下拉列表,允许我从产品表中选择产品

我希望能够创建一个Add或Edit视图,允许我将OrderDate插入OrderTable,并将OrderID和选定的ProductID插入OrderProduct。

我需要在这做什么步骤。

我创建了一个OrderController并勾选了“Add Actions”,然后添加了一个看起来像这样的Create View

@model Test.OrderProduct @{ ViewBag.Title = "Create2"; } 

Create2

@using (Html.BeginForm()) { @Html.ValidationSummary(true)
OrderProduct
@Html.LabelFor(model => model.OrderID)
@Html.EditorFor(model => model.OrderID) @Html.ValidationMessageFor(model => model.OrderID)
@Html.LabelFor(model => model.ProductID)
@Html.EditorFor(model => model.ProductID) @Html.ValidationMessageFor(model => model.ProductID)

}
@Html.ActionLink("Back to List", "Index")

这将创建包含OrderID和ProductID的文本框但不包含日期的视图。

我的控制器CreatePost还没有改变

  [HttpPost] public ActionResult Create(FormCollection collection) { try { var data = collection; // TODO: Add insert logic here // db.Orders.AddObject(collection); return RedirectToAction("Index"); } catch { return View(); } } 

我的问题是,

1.如何将ProductID文本框换成从Product 2填充的下拉列表。如何从FormCollection集合中获取数据? 我只想到了一个foreach,但我不知道如何获得强类型名称

对新手的任何帮助都会非常有帮助。

谢谢!

首先,不要绑定Order实体。 永远不要绑定到EF对象,总是尝试使用ViewModel 。 使View的生活更简单,这就是目标。

所以,有一个像这样的ViewModel:

 public class CreateOrderViewModel { public int OrderId { get; set; } public DateTime OrderDate { get; set; } public int SelectedProductId { get; set; } public IEnumerable Products { get; set; } } 

就是这样。

将其返回到[HttpGet]控制器操作中的View:

 [HttpGet] public ActionResult Create() { var model = new CreateOrderViewModel { Products = db.Products .ToList() // this will fire a query, basically SELECT * FROM Products .Select(x => new SelectListItem { Text = x.ProductName, Value = x.ProductId }); }; return View(model); } 

然后渲染产品列表:(基本HTML除外)

 @model WebApplication.Models.CreateOrderViewModel @Html.DropDownListFor(model => model.SelectedProductId, Model.Products) 

我唯一不知道该怎么做的是绑定到DateTime字段。 我猜你需要一个扩展方法(HTML Helper),它会渲染一个日期选择器或其他东西。 对于此视图(创建新订单),只需默认为DateTime.Now

现在,进入[HttpPost]控制器动作:

 [HttpPost] public ActionResult Create(CreateOrderViewModel model) { try { // TODO: this manual stitching should be replaced with AutoMapper var newOrder = new Order { OrderDate = DateTime.Now, OrderProduct = new OrderProduct { ProductId = SelectedProductId } }; db.Orders.AddObject(newOrder); return RedirectToAction("Index"); } catch { return View(); } } 

现在,我也认为你的EF模型需要工作。

对我来说(用英语表示), 产品可以有很多订单,订单可以有很多产品。

所以,它应该是多对多的。 目前,这是一个带有冗余连接表的1-1。 你是从DB生成的吗? 如果是这样,您的DB可能需要工作。

您应该在Order实体上有一个名为Products的导航属性,该属性引用Product的集合,通过静默连接可以实现多对多中的连接表。

这也意味着您不再拥有DropDownList,而是MultiSelectDropDownList。

谢谢克雷格。 你在MVC的几天(发布时)已经解决了我几天试图从DropDownListFor获取所选值的问题。

在获取DDLF的选定值时,我在“创建”视图中没有任何问题,但“编辑”视图是完全不同的事情 – 我尝试的任何内容都不会在Post中获得所选值。 我注意到所选的值潜伏在ModelState的AttemptedValue中,所以Dr.Google在这里引用了我。

在我看来,我有这个

  @Html.DropDownList(model => model.ContentKeyID, Model.ContentKeys, Model.ContentKeyName) 

其中ContentKeys是通过ViewModel从DB填充的SelectList,而ContentKeyName是精心选择的名称。

奇怪的是,我在视图中以相同的方式填充了另一个DDL。 这个有效。 为什么,我不知道。 它是表格上的第二个DDL,但我看不出它有所作为。

我在其他地方读到可能是我使用Guids作为Id,但这似乎没有什么区别 – 我改为Int32,但我认为不得不 – 我认为这是不同意DDLF的枚举。 Nullables似乎没有任何区别。

现在我已将表单集合添加到Post ActionResult,并使用获取所选值

-视图

  @Html.DropDownList("ContentKey", Model.ContentKeys) 

-in控制器(post)

  contentKeyId = int.Parse(form.GetValue("ContentKey").AttemptedValue); 

一切都很好,我可以继续做更多令人兴奋的事情。 为什么最简单的事情会让你忍受这么久?

在过去的一天左右,我一直在努力解决这个问题。 我将分享我有限的知识,希望它能帮助别人。

请注意,我使用带有预填充列表的单例来保持我的示例应用程序较小(即没有EF或DB交互)。

要显示ProductList,您需要具有包含ProductList的ViewBag或ViewData项。 您可以在控制器中使用类似的function进行设置

  ViewData["ProductList"] = new SelectList(Models.MVCProduct.Instance.ProductList, "Id", "Name", 1); 

然后将您的视图更新为:

  
@Html.DropDownList("ProductList")

对于Post / Create / Update步骤,您需要查看FormCollection以获得结果。 阅读其他post听起来像曾经是这里的一个错误,但现在已经修复,所以确保你有最新的。 对于我的示例,我有一个DropDownList for Product,所以我只获得所选的Id,然后在我的列表中搜索该产品。

  [HttpPost] public ActionResult Create(FormCollection form )//Models.MVCOrder newOrder) { MVC.Models.MVCOrder ord = Models.MVCOrder.Instance.CreateBlankOrder(); //Update order with simple types (eg Quantity) if (TryUpdateModel(ord, form.ToValueProvider())) { ord.Product = Models.MVCProduct.Instance.ProductList.Find(p => p.Id == int.Parse(form.GetValue("ProductList").AttemptedValue)); ord.Attribute = Models.MVCAttribute.Instance.AttributeList.Find(a => a.Id == int.Parse(form.GetValue("attributeId").AttemptedValue)); UpdateModel(ord); return RedirectToAction("Index"); } else { return View(ord); } } 

我最近几天才开始研究MVC3,所以任何关于改进上述内容的建议都会受到赞赏。