2017-03-08 13 views
-1

MVCとEntity FrameworkでWebページを作成しています。 私は広告申込情報が添付された注文を受けており、処理のために複雑なオブジェクトをコントローラに返送したいと考えています。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'コレクションは、WebページにDataが含まれていますが、nullです。

私はそれを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; } 
} 

あなたはコントローラに戻るそれらを投稿したい場合はDisplayForを使用している他のバインドされたフィールドに対して@Html.HiddenFor(m => m.SellingPrice)と同様に追加する必要があります。

注:はあなたの利益のために、あなたのページがブラウザに表示されたときに生成されたHTMLコードを見ていると、name属性を持つ<form>タグの内部で発生しているかのタグを参照してみてください。

+0

ありがとうございます。価格がnullに戻ってこない商品をソートしました。しかし、それらはまだ空です。 –

+0

ちょっと@ColinGenricks問題は、あなたの価格がDisplayForを使って見ることができるということです。 Display値は、コントローラにポスト値を返します。 @ 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は1注文の財産になります。 これが役立つことを願っています。

+0

私はあなたの提案を実装しようとしました。しかし、データソースがOrderCreateGroupなので、私は 'model.OrderCreateGroup.Order.Notes'ではなく' model.Order.Notes'を使っていました。私はこれを入れることができません。これは私のデータソースが間違って設定されていることを意味しますか? –

関連する問題