2014-06-24 71 views
0

我想在ASP.MVC中創建一個顯示引號列表的簡單表單,並允許用戶通過從一個下拉列表將該報價分配給,然後一次性提交表格。在MVC Razor視圖的foreach循環中使用DropDownListFor時出錯

我的問題是,我在一個foreach循環中使用DropDownListFor導致一個錯誤,我不認爲我正在以正確的方式去做。

A(有些簡化)報價如下:

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); 
} 

我的問題是,在我看來,我試圖顯示每個工作訂單和tra的下拉列表並且我認爲我會這樣做的方式是將類屬性「AssignedTo」映射到下拉列表中的值,但這不起作用,因爲DropDownList需要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,然後該ViewModel將返回所有的QuoteItems,但帶有AssignedTo條目。

編輯:

下面安德烈的建議,幫助和帶領我到另一個解決方案,我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.BeginForm。

+0

什麼是錯誤 –

+0

下拉菜單需要一個列表,但是您要傳遞一個字符串值給它。因此給你一個錯誤。將列表傳遞給它,並且您的錯誤將被解決 –

+0

嘗試使用DropDowFor並將名稱指定爲字符串。 – JotaBe

回答

2

得到的一切是正確的,你需要做這裏的常客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。這是ASP.NET MVC視圖中foreach循環的一個非常有名的問題。這裏的問題是,上面的表達式會生成一個select標記,其名稱屬性錯誤,並且在發佈表單時您將不會收到其值。但是,使用常規for循環生成的名稱是正確的。

+0

謝謝安德烈,這似乎是更好的,但是當我提交我的表單我的viewmodel爲null,我已經更新了與細節問題 – Evonet

+0

其實Andrei,我得到一個錯誤與您的代碼行@ Model.QuoteItemCosts [i] - 無法將[]的索引應用於類型爲'System.Collections.Generic.IEnumerable ' – Evonet

+0

對不起,修改爲IList - 一切順利! – Evonet