2017-03-08 87 views
-1

我正在寫一個帶有MVC和實體框架的網頁。 我有附加訂單項的訂單,並希望將複雜對象返回給控制器進行處理。MVC傳遞一個複雜對象到控制器保存

我現在已經包含了所有的代碼。

我的觀點

@model BCMManci.ViewModels.OrderCreateGroup 

@{ 
    ViewBag.Title = "Create"; 
} 
<h2>New Order</h2> 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <h4>@Html.DisplayFor(model => model.Order.Customer.FullName)</h4> 

    <table> 
     <tr> 
      <td><b>Order Date:</b> @Html.DisplayFor(model => model.Order.OrderDate)</td> 
      <td><b>Status:</b> @Html.DisplayFor(model => model.Order.OrderStatus.OrderStatusName)</td> 
     </tr> 
     <tr> 
      <td colspan="2"> 
       <b>Notes</b> 
       @Html.EditorFor(model => model.Order.Notes, new { htmlAttributes = new { @class = "form-control" } }) 
      </td> 
     </tr> 
    </table> 
     @Html.ValidationMessageFor(model => model.Order.Notes, "", new { @class = "text-danger" }) 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 


     <table class="table table-striped table-hover"> 
      <thead> 
       <tr> 
        <td>Name</td> 
        <td>Price</td> 
        <td>Discount</td> 
        <td>Total</td> 
        <td>Quantity</td> 
       </tr> 
      </thead> 
      <tbody> 
       @foreach (var product in Model.ProductWithPrices) 
       { 
        <tr> 
         <td> 
          @Html.DisplayFor(modelItem => product.ProductName) 
         </td> 
         <td> 
          @Html.DisplayFor(modelItem => product.SellingPrice) 
         </td> 
         <td> 
          @Html.DisplayFor(modelItem => product.DiscountPrice) 
         </td> 
         <td> 
          @Html.DisplayFor(modelItem => product.TotalPrice) 
         </td> 
         <td> 
          @Html.EditorFor(modelItem => product.Quantity, new { htmlAttributes = new { @class = "form-control" } }) 
         </td> 
        </tr> 
       } 
      </tbody> 
     </table> 

     <input type="submit" value="Create" class="btn btn-default" /> 
} 
<div class="btn btn-danger"> 
    @Html.ActionLink("Cancel", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 

}

控制器

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create([Bind(Include = "Order,ProductWithPrices,Order.Note,product.Quantity")] OrderCreateGroup order) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       db.Orders.Add(order.Order); 

       foreach (var orderItem in order.ProductWithPrices.Select(item => new OrderItem 
       { 
        OrderId = order.Order.OrderId, 
        ProductId = item.ProductId, 
        Quantity = item.Quantity, 
        ItemPrice = item.SellingPrice, 
        ItemDiscount = item.DiscountPrice, 
        ItemTotal = item.TotalPrice 
       })) 
       { 
        db.OrderItems.Add(orderItem); 
       } 
       db.SaveChanges(); 
       return RedirectToAction("ConfirmOrder", new {id = order.Order.OrderId}); 
      } 
     } 
     catch (DataException /* dex */) 
     { 
      //TODO: Log the error (uncomment dex variable name and add a line here to write a log. 
      ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator."); 
     } 
     ViewBag.Products = db.Products.Where(model => model.IsActive == true); 

     PopulateDropdownLists(); 
     return View(order); 
    } 

數據源

public class OrderCreateGroup 
{ 
    public OrderCreateGroup() 
    { 
     ProductWithPrices = new List<ProductWithPrice>(); 
    } 

    public Order Order { get; set; } 
    public ICollection<ProductWithPrice> ProductWithPrices { get; set; } 
} 

public class ProductWithPrice : Product 
{ 
    public decimal SellingPrice { get; set; } 
    public decimal DiscountPrice { get; set; } 

    public int Quantity { get; set; } 

    public decimal TotalPrice { get; set; } 
} 

但是,表單中輸入的值未被傳遞。所以我無法在控制器中訪問它們。儘管網頁中存在數據,但'productWithPrices'集合爲空。

我試圖使它ASYC也試圖改變ActionLink的按鈕,如下圖所示,但它並沒有得到控制。

@Html.ActionLink("Create", "Create", "Orders", new { orderCreateGoup = Model }, null) 

這是控制器,但它現在沒有意義,因爲參數在頁面的數據源中傳遞。

public ActionResult Create(OrderCreateGroup orderCreateGoup) 

請問,你可以給我這樣做的最佳方式的方向?

+0

請發佈視圖的所有代碼。 – Sxntk

+0

這是因爲您沒有正確生成窗體控件(但您沒有顯示您的代碼!) –

回答

0

在你OrderCreateGroup類初始化集合到一個空列表。

public class OrderCreateGroup 
{ 
    public OrderCreateGroup() 
    { 
     ProductWithPrices = new List<ProductWithPrice>(); 
    } 
    public Order Order { get; set; } 
    public ICollection<ProductWithPrice> ProductWithPrices { get; set; } 
} 

你需要添加@Html.HiddenFor(m => m.SellingPrice),類似的還有,如果你要發佈他們回到控制器使用DisplayFor其他綁定字段。

注:爲了你的利益,試圖看看生成的HTML代碼,當您的網頁瀏覽器中呈現,看到了<form>標籤用name屬性中生成的標記。

+0

謝謝。該排序的產品價格不會返回null。但是,它們仍然是空的。 –

+0

嘿@ColinGenricks問題在於您的價格必然會使用DisplayFor進行查看。 DisplayFor不會將值發回控制器。您需要爲每個需要回發給控制器的價格屬性提供@ Html.HiddenFor()。 – Jinish

+0

謝謝。這是問題所在。我添加了隱藏字段,現在這些值正在通過訂單 –

0

確保你從複雜的對象綁定相應的屬性,如下所示:

@model BCMManci.ViewModels.OrderCreateGroup 

... 
@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 


     ... 
     <div class="form-group"> 
      @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.OrderCreateGroup.Order.Quantity, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.OrderCreateGroup.Order.Quantity, "", new { @class = "text-danger" }) 
      </div> 
     </div> 



     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

注意:model.OrderCreateGroup.Order.Quantity將是一個訂單的財產。 希望這有助於。

+0

我試圖實施您的建議。但是,由於數據源是OrderCreateGroup,我使用的是:'model.Order.Notes'而不是'model.OrderCreateGroup.Order.Notes'。它不允許我這樣做。這是否意味着我的數據源設置不正確? –

相關問題