在MVC Razor视图的foreach循环中使用DropDownListFor时出错
本文关键字:DropDownListFor 出错 循环 Razor MVC 视图 foreach | 更新日期: 2023-09-27 18:10:00
我试图在ASP中创建一个简单的表单。MVC,它显示了一个报价列表,并允许用户通过从下拉列表中选择一个人来创建工作订单,并将该报价分配给他,然后一次性提交表单。
我的问题是我在foreach循环中使用DropDownListFor会导致错误,我不认为我是在正确的方式。
一个(稍微简化的)报价是这样的:
public class QuoteItem
{
public QuoteItem()
{
this.IsWorkOrder = false;
}
[Key]
public int QuoteItemCostID { get; set; }
public string Item { get; set; }
public decimal? Subtotal { get; set; }
public bool IsWorkOrder { get; set; }
[NotMapped]
public string AssignedTo { get; set; }
}
我有一个视图模型配置如下:
public class UnassignedWorkOrdersViewModel
{
public IEnumerable<QuoteItemCost> QuoteItemCosts { get; set; }
public IEnumerable<SelectListItem> Trades { get; set; }
}
和一个像这样的控制器动作:
public ActionResult Unassigned(int id = 0)
{
var trades = db.UserProfiles.Where(u => u.Typpe == "Trade").ToArray().Select(x => new SelectListItem
{
Value = x.FirstName + " " + x.LastName,
Text = x.FirstName + " " + x.LastName
}).ToList();
var quoteItems = db.QuoteItems
.Where(x => x.IsWorkOrder == false)
.ToList();
UnassignedWorkOrdersViewModel viewModel = new UnassignedWorkOrdersViewModel
{
Trades = trades,
QuoteItemCosts = quoteItemCosts
};
return View(viewModel);
}
我的问题是,在我看来,我试图显示每个工作订单和旁边的交易下拉列表,我认为我这样做的方式是将类属性"assigned"映射到下拉列表中的值,但这不起作用,因为下拉列表期望LINQ表达式作为第一个参数:
@model Project.ViewModels.UnassignedWorkOrdersViewModel
@if (Model.QuoteItemCosts.Any())
{
using (Html.BeginForm("Unassigned", "WorkOrder", FormMethod.Post, null))
{
@Html.AntiForgeryToken()
<table>
@foreach (var item in Model.QuoteItemCosts)
{
<tr>
<td style="width:100px;">
<b>Item:</b> @item.Item
</td>
<td style="width:200px;">
<b>Total:</b> @item.Subtotal
</td>
<td>
<b>Assign:</b>
@Html.DropDownListFor(
item.AssignedTo, // THIS LINE CAUSES AN ERROR
Model.Trades,
"", new { @id = "ddlStatus", @style = "width:100%" })
</td>
</tr>
}
</table>
}
我如何解决这个问题,我是否以正确的方式处理这个问题?在表单提交时,我应该期望返回ViewModel,它将返回我所有的QuoteItems,但是如果用户从下拉列表中选择了一个人,则有一个assigndto条目。
编辑:Andrei下面的建议帮助并引导我找到了另一个解决方案,我的DropDownListFor现在看起来像这样:
@Html.DropDownListFor(
m => m.QuoteItemCosts.First(q => q.QuoteItemCostID == item.QuoteItemCostID).AssignedTo,
Model.Trades,
"", new { @id = "ddlStatus", @style = "width:100%" })
但是当我提交表单时,视图模型是空的:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Unassigned(UnassignedWorkOrdersViewModel viewModel)
{
// My viewModel is null
return RedirectToAction("Index");
}
我已经更新了我的剃刀代码,包括一个Html。
为了使一切正确,您需要在这里使用常规的for
循环:
@for (int i = 0; i < Model.QuoteItemCosts.Count; i++)
{
<tr>
<td style="width:100px;">
<b>Item:</b> @Model.QuoteItemCosts[i].Item
</td>
<td style="width:200px;">
<b>Total:</b> @Model.QuoteItemCosts[i].Subtotal
</td>
<td>
<b>Assign:</b>
@Html.DropDownListFor(
m => m.QuoteItemCosts[i].AssignedTo, // THIS LINE CAUSES AN ERROR
Model.Trades,
"", new { @id = "ddlStatus", @style = "width:100%" })
</td>
</tr>
}
现在,你可能想知道为什么不保留foreach
而只使用m => item.AssignedTo
。这是一个非常众所周知的问题与foreach
循环在ASP。. NET MVC视图。这里的问题是,上面的表达式将生成一个具有错误名称属性的select
标记,并且在发布表单时您将无法收到其值。但是,使用常规for循环生成的名称是正确的。