2017-04-06 39 views
3

我的模型包含兩個Order實體類型列表,但僅區分Status屬性的值。當創建Orders時,狀態屬性會自動設置爲In Progress,並在AdminOrders view中放置在Orders In Progress table中。 AdminOrders view有兩個表:Orders In Progress tableOrders Dispatched table,它們將分別填寫Model的列表。模型沒有在post方法中傳遞,它應該從已更改的表單輸入值更新實體

當新訂單Status值從下拉列表改爲dispatched,並在視圖中update單擊按鈕時,發佈請求應被觸發 - 模型傳遞給它。但是,當我調試AdminOrders post方法時,模型參數爲空。

這裏的模型類:

public class AdminOrdersViewModel 
{ 
    public List<Order> OrdersInProgress { get; set; } 
    public List<Order> OrdersDespatched { get; set; } 
} 

這些控制器動作:

[HttpGet] 
[Authorize(Roles = "Admin")] 
public ActionResult AdminOrders() 
{ 
    var model = db.Orders.Where(o => o.Status == "In Progress").ToList(); 
    var model2 = db.Orders.Where(o => o.Status == "Despatched").ToList(); 

    return View(new AdminOrdersViewModel { OrdersInProgress = model, OrdersDespatched = model2 }); 
} 

[HttpPost] 
[Authorize(Roles = "Admin")] 
public async Task<ActionResult> AdminOrders([Bind(Include = "OrdersInProgress, OrdersDespatched")] AdminOrdersViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     foreach (var item in model.OrdersDespatched) 
     { 
      db.Entry(item).State = EntityState.Modified; 
     } 

     foreach (var item2 in model.OrdersInProgress) 
     { 
      db.Entry(item2).State = EntityState.Modified; 
     } 

     await db.SaveChangesAsync(); 

     var ordersInProgress = db.Orders.Where(o => o.Status == "In Progress").ToList(); 
     var ordersDespatched = db.Orders.Where(o => o.Status == "Despatched").ToList(); 

     return View(new AdminOrdersViewModel { OrdersDespatched = ordersDespatched, OrdersInProgress = ordersInProgress }); 
    } 

    return View(model); 
} 

Get要求AdminOrders方法,每個型號列表的實體被更新,新的模式是提供給查看何時返回視圖,因此頁面應該更新並且根據狀態屬性將訂單移動到正確的表格。但是模型留空。

在視圖形式分配視圖的模型Post方法模型參數:

@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new 
    { 
     enctype = "multipart/form-data" 
    })) 
    { 
    } 

我也試圖在兩個新的列表來傳遞Post方法與模型的列表的形式單獨分配請求,但接收錯誤。我如何確保Post請求將更新的模型傳遞給AdminOrders post方法?

完整視圖頁面代碼如下:

@model ValueVille.Models.AdminOrdersViewModel 

@{ 
    ViewBag.Title = "Orders"; 

} 

<div class="main-content-container"> 

    <h1>New Orders In Progress</h1> 
@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new 
{ 
    enctype = "multipart/form-data" 
})) 
{ 
     @Html.AntiForgeryToken() 

     <table class="panel panel-default table cart-table"> 
      <tr> 
       <th> 
        Order ID 
       </th> 
       <th> 
        Total 
       </th> 
       <th> 
        Date 
       </th> 
       <th> 
        Status 
       </th> 
      </tr> 
      @foreach (var item in Model.OrdersInProgress) 
      { 
       <tr> 
        <td> 
         <a href="@Url.Action("OrderDetails", "Home", new { id = item.OrderId })"> 
          @item.OrderId 
         </a> 
        </td> 
        <td> 
         £@item.Total 
        </td> 
        <td> 
         @item.OrderDate 
        </td> 
        <td> 
         @{ 
          List<SelectListItem> listItems = new List<SelectListItem>(); 
          listItems.Add(new SelectListItem 
          { 
           Text = item.Status, 
           Value = "Option1" 
          }); 
          listItems.Add(new SelectListItem 
          { 
           Text = "Despatched", 
           Value = "Option2", 

          }); 

         } 

         @Html.DropDownListFor(m => item.Status, listItems, item.Status) 
        </td> 
       </tr> 
          } 

     </table> 

     <h1>Orders Despatched</h1> 

     <table class="panel panel-default table cart-table"> 
      <tr> 
       <th> 
        Order ID 
       </th> 
       <th> 
        Total 
       </th> 
       <th> 
        Date 
       </th> 
       <th> 
        Status 
       </th> 
      </tr> 
      @foreach (var item in Model.OrdersDespatched) 
      { 
       <tr> 
        <td> 
         <a href="@Url.Action("OrderDetails", "Home", new { id = item.OrderId })"> 
          @item.OrderId 
         </a> 
        </td> 
        <td> 
         £@item.Total 
        </td> 
        <td> 
         @item.OrderDate 
        </td> 
        <td> 
         @{ 
          List<SelectListItem> listItems = new List<SelectListItem>(); 
          listItems.Add(new SelectListItem 
          { 
           Text = item.Status, 
           Value = "Option1" 
          }); 
          listItems.Add(new SelectListItem 
          { 
           Text = "Despatched", 
           Value = "Option2", 

          }); 

         } 

         @Html.DropDownListFor(m => item.Status, listItems) 
        </td> 
       </tr> 
          } 

     </table> 

     <div class="panel-body form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Update" class="btn btn-success" /> 
      </div> 
     </div> 

          } 



</div> 
+0

當您嘗試單獨傳遞列表時會得到什麼錯誤? –

+0

另外,你的下拉列表是什麼樣的?他們的名字是什麼? –

+0

我已更新問題以包含完整視圖頁面代碼。當單獨傳遞列表時,沒有錯誤,但在發佈請求中傳遞的列表是空的 - 因此ModelState是無效的。 – naz786

回答

-1

好了,我看到你在做什麼?

出於某種原因,在asp.net MVC是看起來這應該工作:

@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new 
{ 
    enctype = "multipart/form-data" 
})) 
{ 
//Form contents 
} 

我傳遞模型的權利?好吧,我想不是,因爲它不起作用。

你必須做的是這樣的事情(添加兩個隱藏字段的形式):

@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new 
{ 
    enctype = "multipart/form-data" 
})) 
{ 
    @Html.HiddenFor(x => x.OrdersInProgress) 
    @Html.HiddenFor(x => x.OrdersDespatched) 
} 

然後將它設置爲取兩個列表中的控制器動作。

我試圖將複雜對象(pocos或其他)傳遞給控制器​​時發現此問題,並且發現您必須完全按照它們的名稱包含對象,並且它必須與控制器所期望的內容相匹配。所以如果你有一個名爲OrdersInProgressList<Order>,那麼你必須將那個類型的列表與那個確切的名稱一起傳遞給控制器​​,該控制器接受具有該確切名稱的該類型的列表。表單中隱藏的控件應該以該名稱傳遞該列表。如果該清單變成空白,請檢查它的名稱是否正確。

+0

這不回答我的問題,但謝謝你的嘗試。 – naz786

1

修改您的視圖模型到:

public class AdminOrdersViewModel 
{ 
    public List<Order> OrdersInProgress { get; set; } 
    public List<Order> OrdersDespatched { get; set; } 
    public List<Status> OrderStatuses { get; set; } 
} 

現在視圖應該看起來像:

@model ValueVille.Models.AdminOrdersViewModel 
@{ 
    ViewBag.Title = "Orders"; 
} 

<div class="main-content-container"> 
    <h1>New Orders In Progress</h1> 
    @using (Html.BeginForm("AdminOrders", "Manage", FormMethod.Post, new { enctype = "multipart/form-data" })) 
    { 
     @Html.AntiForgeryToken() 

     <table class="panel panel-default table cart-table"> 
      <thead> 
       <tr> 
        <th>Order ID</th> 
        <th>Total</th> 
        <th>Date</th> 
        <th>Status</th> 
       </tr> 
      </thead> 
      <tbody> 
       @for (int i = 0; i < Model.OrdersInProgress.Count(); i++) 
       { 
        <tr> 
         <td> 
          <a href="@Url.Action("OrderDetails", "Home", new { id = Model.OrdersInProgress[i].OrderId })">@Model.OrdersInProgress[i].OrderId</a> 
          @Html.HiddenFor(x => x.Model.OrdersInProgress[i].OrderId) 
         </td> 
         <td> 
          £@Model.OrdersInProgress[i].Total 
          @Html.HiddenFor(x => x.Model.OrdersInProgress[i].Total) 
         </td> 
         <td> 
          @Model.OrdersInProgress[i].OrderDate 
          @Html.HiddenFor(x => x.Model.OrdersInProgress[i].OrderDate) 
         </td> 
         <td> 
          @Html.DropDownListFor(m => Model.OrdersInProgress[i].Status, new SelectList(Model.OrderStatuses, "Id", "StatusName")) 
         </td> 
        </tr> 
       } 
      </tbody> 
     </table> 

     <h1>Orders Despatched</h1> 
     <table class="panel panel-default table cart-table"> 
      <thead> 
       <tr> 
        <th>Order ID</th> 
        <th>Total</th> 
        <th>Date</th> 
        <th>Status</th> 
       </tr> 
      </thead> 
      <tbody> 
       @for (int i = 0; i < Model.OrdersDespatched.Count(); i++) 
       { 
        <tr> 
         <td> 
          <a href="@Url.Action("OrderDetails", "Home", new { id = Model.OrdersDespatched[i].OrderId })">@Model.OrdersDespatched[i].OrderId</a> 
          @Html.HiddenFor(x => x.Model.OrdersDespatched[i].OrderId) 
         </td> 
         <td> 
          £@Model.OrdersDespatched[i].Total 
          @Html.HiddenFor(x => x.Model.OrdersDespatched[i].Total) 
         </td> 
         <td> 
          @Model.OrdersDespatched[i].OrderDate 
          @Html.HiddenFor(x => x.Model.OrdersDespatched[i].OrderDate) 
         </td> 
         <td> 
          @Html.DropDownListFor(m => Model.OrdersDespatched[i].Status, new SelectList(Model.OrderStatuses, "Id", "StatusName")) 
         </td> 
        </tr> 
       } 
      </tbody> 
     </table> 

     <div class="panel-body form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Update" class="btn btn-success" /> 
      </div> 
     </div> 
    } 
</div> 

控制器方法應該是這樣的:

[HttpPost] 
public async Task<ActionResult> AdminOrders(AdminOrdersViewModel model) 
{ 
    // do stuff 
} 

假設你Status模型somethig如:

public class Status 
{ 
    public int Id { get; set; } 
    public string StatusName { get; set; } 
} 

您可以從您上面列表中的下拉列表:

@Html.DropDownListFor(m => Model.OrdersDespatched[i].Status, new SelectList(Model.OrderStatuses, "Id", "StatusName")) 

PS:另外,還要確保您的分配在Get方法狀態列表。

+0

我不需要創建一個下拉列表,我需要能夠成功發佈更新視圖模型的請求。 – naz786

+0

上面的代碼將發佈具有更新狀態的列表。 –

+1

我從我的同事那裏發現,他說過這樣的話是不可能的,因爲MVC無法同時更新數據庫和視圖。這必須通過Ajax完成,我將嘗試實現,並在完成後回覆答案。謝謝Cristian的迴應,我發現你創建下拉列表的方式非常有用。 :d – naz786