2012-04-24 4 views
1

나는 사용자가 장바구니의 내용을 '체크 아웃'할 수있는 컨트롤러와 뷰를 가지고 있습니다.ViewModel이 POST에서 업데이트되지 않습니다.

내 CheckoutController가 주문 모델을 Checkout보기로 반환 할 때 모두 정상적으로 작동했습니다. 그러나 Checkout보기에 장바구니의 내용을 표시하여 Order 및 CartItem이 포함 된 뷰 모델을 사용하도록 Controller 및 View를 수정하려고합니다.

CheckoutViewModel을 만들고이 viewmodel을 사용하기 위해 GET : 및 POST : ActionResults를 수정했습니다.

문제는 CheckOutViewModel 제대로 POST 동안 채워되지 않을 수 있습니다 :

내가이 라인 'checkoutViewModel.Order.Username = 사용자에 대한 오류에'개체의 인스턴스로 설정되지 않았습니다 개체 참조 '를 얻고있다. Identity.Name; ' POST : ActionResult하지만 정확히 무엇이 인스턴스화되지 않았는지 확실하지 않습니다.

필요한 경우 CheckoutViewModel 대신 Oreder 모델을 사용하여 코딩 된 원본 코드를 게시 할 수 있습니다.

간단한 sturctural 또는 구문 문제가 있다고 확신합니다. MVC에서 작업하는 가장 좋은 방법을 고민하고 있기 때문에 무엇인지 알 수 없습니다.

GET : ActionResult

//GET: /Checkout/AddressAndPayment 
    public ActionResult AddressAndPayment() 
    { 
     //To pre-populate the form, create a new Order object and get the ShoppingCart, populate the ViewModel and pass it to the view 
     var order = new Order(); 
     order.Username = User.Identity.Name; 
     MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */); 
     storeDB.SaveChanges(); 

     var cart = ShoppingCart.GetCart(this.HttpContext); 

     // Set up our ViewModel 
     var viewModel = new CheckoutViewModel 
     { 
      CartItems = cart.GetCartItems(), 
      CartTotal = cart.GetTotal(), 
      Order = order 
     }; 

     // Return the view 
     return View(viewModel); 
    } 

POST : ActionResult

 //POST: /Checkout/AddressAndPayment 
    [HttpPost] 
    public ActionResult AddressAndPayment(FormCollection values) 
    { 
     var checkoutViewModel = new CheckoutViewModel(); 
     TryValidateModel(checkoutViewModel); 

     try 
     { 
      checkoutViewModel.Order.Username = User.Identity.Name; 
      checkoutViewModel.Order.OrderDate = DateTime.Now; 
      //Save Order 
      storeDB.Orders.Add(checkoutViewModel.Order); 
      storeDB.SaveChanges(); 
      //Process the order 
      var cart = ShoppingCart.GetCart(this.HttpContext); 
      cart.CreateOrder(checkoutViewModel.Order); 
      storeDB.SaveChanges(); 
      //Send 'Order Confirmation' email 
      ViewData["order"] = checkoutViewModel.Order; 
      UserMailer.OrderConfirmation(checkoutViewModel.Order).SendAsync(); 

      return RedirectToAction("Complete", new { id = checkoutViewModel.Order.OrderID }); 
     } 
     catch 
     { 
      //Invalid - redisplay with errors 
      return View(checkoutViewModel); 
     } 
    } 

보기

@model OrderUp.ViewModels.CheckoutViewModel 
@{ 
    ViewBag.Title = "AddressAndPayment"; 
} 
<script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@using (Html.BeginForm()) { 
@Html.ValidationSummary(true) 
<h2>Pick Up Details</h2> 
<fieldset> 
    <legend>When are you gonna be hungry?</legend> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Order.Phone) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Order.Phone) 
     @Html.ValidationMessageFor(model => model.Order.Phone) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Order.PickUpDateTime) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Order.PickUpDateTime) 
     @Html.ValidationMessageFor(model => model.Order.PickUpDateTime) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Order.Notes) 
    </div> 
    <div class="editor-multiline-field"> 
     @Html.EditorFor(model => model.Order.Notes) 
     @Html.ValidationMessageFor(model => model.Order.Notes) 
    </div> 
</fieldset> 
<input type="submit" value="Submit Order" /> 
} 
<div style="height:30px;"></div> 
<h3> 
    <em>Review</em> your cart: 
</h3> 
<table> 
<tr> 
    <th> 
     Menu Item 
    </th> 

    <th> 
     Price (each) 
    </th> 
    <th> 
     Notes 
    </th> 
    <th> 
     Quantity 
    </th> 
    <th></th> 
</tr> 
@foreach (var item in Model.CartItems) 
{ 
    <tr id="[email protected]"> 
     <td> 
      @Html.ActionLink(item.MenuItem.Name, "Details", "Store", new { id = item.MenuItemID }, null) 
     </td> 

     <td> 
      @Html.DisplayFor(modelItem => item.MenuItem.Price) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Notes) 
     </td> 
     <td id="[email protected]"> 
      @item.Count 
     </td> 
     <td> 
     </td> 
    </tr> 
} 
<tr> 
    <td > 
     Total 
    </td> 
    <td id="cart-total"> 
     @String.Format("${0:F2}", Model.CartTotal) 
    </td> 
    <td> 
    </td> 
    <td> 
    </td> 
    <td> 
    </td> 
</tr> 
</table> 
+0

당신이 별도 제작에만 있기 때문에 나는 당신의 DB에 저장, 여기에 작은 변화를 제안 - 트랜잭션에서 그들을 포장하기 때문에 저장 2가 실패 할 경우 전체 방법은 롤백과에 DB를 떠날 수 없다 모순 된 상태. –

답변

2

당신은 유해야 se CheckViewViewModel을 HttpPost 메소드의 입력 매개 변수로 사용하고 디버그를 시도하고 양식 게시 후에도 해당 모델을 채우지 못하는지 확인하십시오.

[HttpPost] 
    public ActionResult AddressAndPayment(CheckOutViewModel checkoutViewModel) 
    { 
     TryValidateModel(checkoutViewModel); 

     try 
     { 
      checkoutViewModel.Order.Username = User.Identity.Name; 
      checkoutViewModel.Order.OrderDate = DateTime.Now; 
      //Save Order 
      storeDB.Orders.Add(checkoutViewModel.Order); 
      storeDB.SaveChanges(); 
      //Process the order 
      var cart = ShoppingCart.GetCart(this.HttpContext); 
      cart.CreateOrder(checkoutViewModel.Order); 
      storeDB.SaveChanges(); 
      //Send 'Order Confirmation' email 
      ViewData["order"] = checkoutViewModel.Order; 
      UserMailer.OrderConfirmation(checkoutViewModel.Order).SendAsync(); 

      return RedirectToAction("Complete", new { id = checkoutViewModel.Order.OrderID }); 
     } 
     catch 
     { 
      //Invalid - redisplay with errors 
      return View(checkoutViewModel); 
     } 
    } 
+0

완벽한! 고마워요 @ MoXplod. 그것은 그것을 고쳤다. 을 사용할 때 ViewModel이 자동으로 다시 전달 될지 확신하지 못했습니다. – Dhaust

관련 문제