C# mvc3编辑表单中的下拉列表
这可能很简单,但我似乎无法独自解决。 我创建了一个简单的db和实体模型,如下所示 我正在尝试创建一个创建表单,允许我添加新订单。我一共有3个表,所以我要做的是有一个表单,允许用户输入订单日期,还有一个下拉列表,允许我从产品表中选择产品 我希望能够创建一个添加或编辑视图,允许我将OrderDate插入OrderTable,并将OrderID和所选ProductID插入OrderProduct 我需要在这里执行哪些步骤 我已经创建了一个OrderController并勾选了“添加操作”,然后添加了一个创建视图,如下所示C# mvc3编辑表单中的下拉列表,c#,asp.net-mvc-3,razor,html-helper,C#,Asp.net Mvc 3,Razor,Html Helper,这可能很简单,但我似乎无法独自解决。 我创建了一个简单的db和实体模型,如下所示 我正在尝试创建一个创建表单,允许我添加新订单。我一共有3个表,所以我要做的是有一个表单,允许用户输入订单日期,还有一个下拉列表,允许我从产品表中选择产品 我希望能够创建一个添加或编辑视图,允许我将OrderDate插入OrderTable,并将OrderID和所选ProductID插入OrderProduct 我需要在这里执行哪些步骤 我已经创建了一个OrderController并勾选了“添加操作”,然后添加了
@model Test.OrderProduct
@{
ViewBag.Title = "Create2";
}
<h2>Create2</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>OrderProduct</legend>
<div class="editor-label">
@Html.LabelFor(model => model.OrderID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.OrderID)
@Html.ValidationMessageFor(model => model.OrderID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ProductID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProductID)
@Html.ValidationMessageFor(model => model.ProductID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
我的问题是,
1.如何将ProductID文本框替换为从Product填充的下拉列表
2.如何从FormCollection获取数据?我只想到了一个foreach,但我不知道如何获得强类型名称
对新手的任何帮助都会很有帮助
谢谢大家! 在过去的一天左右,我也一直在努力解决这个问题。我将分享我有限的知识,希望它能帮助别人 请注意,我使用带有预填充列表的单例来保持示例应用程序的小规模(即没有EF或DB交互) 要显示ProductList,您需要有一个包含ProductList的ViewBag或ViewData项。 您可以在控制器中通过以下方式进行设置
ViewData["ProductList"] = new SelectList(Models.MVCProduct.Instance.ProductList, "Id", "Name", 1);
然后将视图更新为类似以下内容:
<div class="editor-field">@Html.DropDownList("ProductList")</div>
@Html.DropDownList(“产品列表”)
对于Post/Create/Update步骤,您需要查看FormCollection以获得结果。在阅读其他帖子时,听起来这里曾经有一个bug,但现在已经修复了,所以请确保您拥有最新的bug。例如,我有一个产品的下拉列表,所以我只需获取所选Id,然后在列表中搜索该产品
[HttpPost]
public ActionResult Create(FormCollection form )//Models.MVCOrder newOrder)
{
MVC.Models.MVCOrder ord = Models.MVCOrder.Instance.CreateBlankOrder();
//Update order with simple types (e.g. Quantity)
if (TryUpdateModel<MVC.Models.MVCOrder>(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);
}
}
[HttpPost]
公共操作结果创建(FormCollection表单)//Models.MVCOrder newOrder)
{
MVC.Models.MVCOrder ord=Models.MVCOrder.Instance.CreateBlankOrder();
//使用简单类型(例如数量)更新订单
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));
更新模型(ord);
返回操作(“索引”);
}
其他的
{
返回视图(ord);
}
}
我最近几天才开始研究MVC3,因此如果您能提供任何关于改进上述内容的建议,我将不胜感激。首先,不要绑定到订单实体。永远不要绑定到EF对象,始终尝试使用视图模型。使视图的生活更简单,这就是本文的目标 因此,请使用如下视图模型:
public class CreateOrderViewModel
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public int SelectedProductId { get; set; }
public IEnumerable<SelectListItem> Products { get; set; }
}
然后呈现产品列表:(基本HTML除外)
我唯一不知道怎么做的就是绑定到DateTime字段。我猜您可能需要一个扩展方法(HTML助手),用于呈现日期选择器之类的东西。对于此视图(创建新订单),只需默认设置为DateTime.Now
现在,进入[HttpPost]
控制器操作:
[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);
}
[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的冗余联接表。你是从数据库生成的吗?如果是这样,您的数据库可能需要工作
您应该在订单实体上有一个名为产品的导航属性,该属性引用了产品的集合,通过对多对多中的联接表进行无提示联接而成为可能
这也意味着你不再有DropDownList,而是一个多选DropDownList。谢谢Craig。您发布MVC的几天(截至发帖时)解决了我几天来试图从DropDownListFor获取所选值的问题 我在Create视图中获取DDLF的选定值没有问题,但是Edit视图是一个完全不同的问题——我所做的任何尝试都无法在帖子中获取选定值。我注意到所选的值潜伏在ModelState的AttemptedValue中,所以Google博士把我介绍到这里 我有这个想法
@Html.DropDownList(model => model.ContentKeyID, Model.ContentKeys, Model.ContentKeyName)
其中ContentKeys是通过ViewModel从DB填充的选择列表,ContentKeyName是当前选择的名称
wierd的事情是,我在视图上以相同的方式填充了另一个DDL。这个有效。为什么,我不知道。这是表单上的第二个DDL,但我看不出有什么不同
我在其他地方读到,可能是我使用了guid作为Id,但这似乎没有什么区别——我改为Int32,但我不认为我必须这样做——我认为是enum不同意DDLF。空值看起来也没有什么区别
现在,我已经将表单集合添加到PostActionResult中,并使用
-看法
-财务主任(职位)
一切都很好,我可以继续做更令人兴奋的事情。为什么最简单的事情能让你坚持这么久?有趣的是,这正是我目前的问题,但这里没有人回答。我原以为MVC迷们会在2秒钟内跳到这个上面。在上面的
[HttpGet]
方法中,我不断收到一个错误,告诉我我不能隐式地将int转换为value=x.id
位的字符串!我添加了一个ToString()
,但是我得到了这个错误:错误7无法即时消息
[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();
}
}
@Html.DropDownList(model => model.ContentKeyID, Model.ContentKeys, Model.ContentKeyName)
@Html.DropDownList("ContentKey", Model.ContentKeys)
contentKeyId = int.Parse(form.GetValue("ContentKey").AttemptedValue);